Правильный способ свободной памяти возвращенной переменной

Я создал функцию, предназначенную для ввода пользователя. Он требует, чтобы память была назначена переменной, содержащей вход пользователя; однако эта переменная возвращается в конце функции. Каков правильный способ освободить выделенную память/вернуть значение переменной?

Вот код:

char *input = malloc(MAX_SIZE*sizeof(char*));
int i = 0;
char c;

while((c = getchar()) != '\n' && c != EOF) {
    input[i++] = c;
}

return input;

Должен ли я вернуть адрес ввода и освободить его после его использования?

Интересно, как правильно выбрать входную переменную.

Ответ 1

Это довольно просто, если вы переходите к free() тому же указателю, возвращаемому malloc(), это хорошо.

Например

char *readInput(size_t size)
 {
    char *input;
    int   chr;
    input = malloc(size + 1);
    if (input == NULL)
        return NULL;
    while ((i < size) && ((chr = getchar()) != '\n') && (chr != EOF))
        input[i++] = chr;
    input[size] = '\0'; /* nul terminate the array, so it can be a string */
    return input;
 }

 int main(void)
  {
     char *input;
     input = readInput(100);
     if (input == NULL)
         return -1;
     printf("input: %s\n", input);
     /* now you can free it */
     free(input);
     return 0;
  }

То, что вы никогда не должны делать, это что-то вроде

free(input + n);

потому что input + n не является возвратом указателя на malloc().

Но ваш код, есть другие проблемы, которые вы должны позаботиться о

  • Вы выделяете пространство для MAX_SIZE char, поэтому вам следует умножить на sizeof(char), который равен 1 вместо sizeof(char *), который выделяет указатели MAX_SIZE, а также вы можете сделать MAX_SIZE параметр функции, потому что, если вы назначаете фиксированный буфер, вы можете определить массив в main() с размером MAX_SIZE, как char input[MAX_SIZE], и передать его в readInput() в качестве параметра, тем самым избегая malloc() и free().

  • Вы выделяете столько места, но вы не предотвращаете переполнение в цикле while, вы должны убедиться, что i < MAX_SIZE.

Ответ 2

Вы можете написать функцию с типом возвращаемого значения char*, return input и попросить пользователя вызвать free после их выполнения с данными.

Вы также можете попросить пользователя передать в буфер надлежащего размера вместе с ограничением размера буфера и вернуть количество символов в буфер.

Ответ 3

Это классический случай c. Функция mallocs для своего результата, вызывающий должен освободить возвращаемое значение. Теперь вы ходите по тонкому льду утечек памяти. 2 причины

Сначала; вы не можете передавать свободное требование принудительно (т.е. компилятор или время выполнения не могут помочь вам - контрастировать с указанием типов аргументов). Вам просто нужно документировать его где-то и надеяться, что вызывающий пользователь прочитал ваши документы

Во-вторых: даже если вызывающий абонент знает, что может освободить результат, он может совершить ошибку, будет принят некоторый путь ошибки, который не освободит память. Это не вызывает немедленной ошибки, все работает, но после запуска в течение 3 недель ваше приложение вылетает из-за нехватки памяти

Вот почему так много "современных" языков фокусируются на этой теме, умных указателях С++, сборке мусора Java, С# и т.д.,...