Каков правильный способ записи функции C Возврат массива char?
Я хорошо знаком с Java, а не с C.
В Java, если у меня есть метод, который что-то делает и возвращает строку, он будет выглядеть так:
private String doSomething(...) {
String s;
// do something;
return s;
}
Синтаксический эквивалент в C не будет работать и не прав:
char* doSomething(...) {
char s[100];
// do something;
return s;
}
конечно, я могу сделать:
char* doSomething(...) {
char *s;
s = malloc(100 * sizeof(char));
// do something;
return s;
}
который будет работать (я думаю!), но редко вижу коды, делающие этот путь (это потому, что он излишне заполняет кучу?)
чаще всего я вижу:
bool doSomething(char *s) {
// do something that copies chars to s
return true;
}
И вызывающие операторы:
char s[100];
doSomething(s);
Что делать, если я не знаю размер массива char до самой функции? то есть я не смог бы объявить массив char вне функции, а затем передать его.
Каким будет правильный способ справиться с таким сценарием?
Ответы
Ответ 1
Пример случая статического распределения (вы должны думать о максимальном размере буфера во время компиляции)
buf[MAX_NO];
do(buf, MAX_NO);
_Bool do(char *s, size_t len) {
// use len as boundary in your operations
}
или динамический случай распределения (используя malloc, как вы сказали, и используя указатели для сохранения местоположения и размера буфера)
char *s = NULL;
size_t final_len;
do(&s, &final_len);
_Bool do(char** s, size_t* final_len) {
size_t len = discoverSize();
char* buf = (char*) malloc(sizeof(char) * len);
*s = buf; //save memory location
*final_len = len; //save buffer size
// use len as boundary in your operations
}
// do whatever
free(s); //remember to free the buffer for politeness
Ответ 2
Пусть вызывающий код отвечает за выделение памяти. Перейдите в буфер и длину буфера в примере 2:
bool doSomething(char *s, size_t buflen)
{
// do something that copies chars to s up to max of buflen
return true;
}
Это уменьшает утечки, поскольку вызывающий код контролирует управление памятью.
Ответ 3
Если вы не можете знать правильный размер возвращаемой строки, используйте решение malloc
. Конечно, вы должны free
строку, после того как вы закончите с ней.
Ответ 4
Вы не можете вернуть массив в C.
Вы можете вернуть указатель, и вы должны изучить (прочитав хорошую книгу по программированию на языке C) разницу между массивами и указателями.
Общей идиомой является возврат динамически выделенного указателя. Затем вы должны иметь соглашение о том, кто освободит указатель.
Вы также можете вернуть структуру, содержащую массив.
добавлений
Если вы хотите иметь сборщика мусора на C, попробуйте сборщик мусора Boehm
Ответ 5
Самый безопасный способ заключается в том, чтобы оставить ответственность за выделение вызывающему абоненту, как говорят другие.
Но, если вам не нужен реентер-код и простота Java, синтаксический рабочий эквивалент в C:
char* doSomething(...) {
static char s[100];
// do something;
return s;
}