Подтвердить что ты не робот

Каков правильный способ записи функции 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 вне функции, а затем передать его.

Каким будет правильный способ справиться с таким сценарием?

4b9b3361

Ответ 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;
}