Mam funkcję ciągu, który akceptuje wskaźnik do łańcucha źródłowego i zwraca wskaźnik do łańcucha docelowego. Ta funkcja obecnie działa, ale obawiam się, że nie stosuję się do najlepszych praktyk odnawiając malloc, realloc i za darmo.najlepsza praktyka zwracania zmiennej długości łańcucha w c
Rzeczą, która różni się w mojej funkcji jest to, że długość docelowego łańcucha nie jest taka sama jak łańcucha źródłowego, więc realloc() musi być wywołana w mojej funkcji. Wiem, że od patrzenia na docs ...
http://www.cplusplus.com/reference/cstdlib/realloc/
że adres pamięci może się zmienić po realloc. Oznacza to, że nie mogę "przekazać przez odniesienie", tak jak programista C może dla innych funkcji, muszę zwrócić nowy wskaźnik.
więc prototypem mojej funkcji jest następująca:
//decode a uri encoded string
char *net_uri_to_text(char *);
nie podoba mi się sposób, w jaki ja to robię, bo muszę uwolnić wskaźnik po uruchomieniu funkcji:
char * chr_output = net_uri_to_text("testing123%5a%5b%5cabc");
printf("%s\n", chr_output); //testing123Z[\abc
free(chr_output);
Co oznacza, że malloc() i realloc() są wywoływane wewnątrz mojej funkcji, a free() jest wywoływana poza moją funkcją.
Mam doświadczenie w językach wysokiego poziomu (Perl, plpgsql, bash), więc mój instynkt jest właściwy hermetyzacji o takich rzeczach, ale to może nie być najlepsze praktyki w C
na pytanie: Czy mój najlepsza praktyka, czy jest lepszy sposób, w jaki powinienem podążać?
pełny przykład
kompiluje i uruchamia dwa ostrzeżenia na niewykorzystane argc i argv argumentów, można zignorować te dwa ostrzeżenia.
przyklad.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *net_uri_to_text(char *);
int main(int argc, char ** argv) {
char * chr_input = "testing123%5a%5b%5cabc";
char * chr_output = net_uri_to_text(chr_input);
printf("%s\n", chr_output);
free(chr_output);
return 0;
}
//decodes uri-encoded string
//send pointer to source string
//return pointer to destination string
//WARNING!! YOU MUST USE free(chr_result) AFTER YOU'RE DONE WITH IT OR YOU WILL GET A MEMORY LEAK!
char *net_uri_to_text(char * chr_input) {
//define variables
int int_length = strlen(chr_input);
int int_new_length = int_length;
char * chr_output = malloc(int_length);
char * chr_output_working = chr_output;
char * chr_input_working = chr_input;
int int_output_working = 0;
unsigned int uint_hex_working;
//while not a null byte
while(*chr_input_working != '\0') {
//if %
if (*chr_input_working == *"%") {
//then put correct char in
sscanf(chr_input_working + 1, "%02x", &uint_hex_working);
*chr_output_working = (char)uint_hex_working;
//printf("special char:%c, %c, %d<\n", *chr_output_working, (char)uint_hex_working, uint_hex_working);
//realloc
chr_input_working++;
chr_input_working++;
int_new_length -= 2;
chr_output = realloc(chr_output, int_new_length);
//output working must be the new pointer plys how many chars we've done
chr_output_working = chr_output + int_output_working;
} else {
//put char in
*chr_output_working = *chr_input_working;
}
//increment pointers and number of chars in output working
chr_input_working++;
chr_output_working++;
int_output_working++;
}
//last null byte
*chr_output_working = '\0';
return chr_output;
}
Podoba mi się część '*"% "'. : D –
Dzięki, właśnie się dowiedziałem, że ''% ''działa. :) – Michael
Jeśli zawiniesz swój kod między backticks ('), wtedy będą one sformatowane jako kod –