Как правильный способ написать функцию C, возвращая массив Char?

StackOverflow https://stackoverflow.com/questions/8311131

  •  25-10-2019
  •  | 
  •  

Вопрос

Я очень знаком с 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 до самой внутри функции? т.е. я не смогу объявить массив ЧАР за пределами функции, а затем передать его.

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

Это было полезно?

Решение

Пример случая статического распределения (вы обязаны подумать о максимальном размере буфера во время компиляции)

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:

bool doSomething(char *s, size_t buflen)
{ 
    // do something that copies chars to s up to max of buflen
    return true; 
} 

Это имеет тенденцию уменьшать утечки, поскольку вызывающий код контролирует управление памятью.

Ибо, когда вы не можете знать правильный размер возвращаемой строки, используйте malloc решение. Конечно, вы должны free Строка, после того, как вы закончите с ней.

Вы не можете вернуть массив в C.

Вы можете вернуть указатель И вы должны учиться (прочитав хорошее книга о программировании в В Язык) Разница между массивами и указателями.

Общая идиома - вернуть динамически выделенный указатель. Тогда у вас должно быть соглашение, сообщающее, кто освободит указатель.

Вы также можете вернуть структуру, содержащую массив.

добавка

Если вы хотите иметь сборщик мусора в C, попробуйте Коллектор мусора Бома

Самый безопасный способ - оставить ответственность за выделение на звонящего, как сказали другие.

Но, если вам не нужен код повторного въезда и простота Java, синтаксический рабочий эквивалент в C:

char* doSomething(...) {
    static char s[100];
    // do something;
    return s;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top