Измените (уменьшите) массив символов с помощью realloc и проверьте успешность - PullRequest
0 голосов
/ 13 ноября 2018

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

Проблема в том, что я понятия не имею, действительно ли программа это делает? Я не получаю сообщение об ошибке и правильный вывод, но действительно ли неиспользуемая память освобождена?

char *input=(char*)malloc(100);
gets(input);
int a = strlen(input);
input = realloc(input, a+1);

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Не приводить результат *alloc() в C. Это не нужно, только добавляет беспорядок в код и в худшем случае скрывает ошибки, такие как забывание #inlude <stdlib.h> для *alloc().

* 1005.* Строка
input = realloc(input, a+1);

проблематична, потому что вы потеряете предыдущее значение указателя, если realloc() завершится неудачно и вернет NULL.Лучше:

char *new_input = realloc(input, a+1);
if(!new_input) {
    free(input);
    // print some error message
    return EXIT_FAILURE;
}

// everything fine:
input = new_input;

// use input

free(input);

PS: Также, как другие отметили в комментариях: уберите gets() из своего словаря.Притворись, что его никогда не было.Вместо этого используйте fgets().

0 голосов
/ 13 ноября 2018

Я предлагаю вам изменить свой алгоритм. В C вы можете зарезервировать достаточно большой буфер в стеке, а затем, прочитав входные данные, выделить постоянный буфер в куче:

#define BIG_ENOUGH 4096
char *get_line(FILE *fp)

{
    char buf[BIG_ENOUGH] = "";

    return fgets(buf, BIG_ENOUGH - 1, fp) ? strdup(buf) : NULL;
}
0 голосов
/ 13 ноября 2018

Обычно единственный способ проверить успешность функций-распределителей - проверить возвращаемый указатель с помощью вызова realloc() против указателя NULL. Если возвращенный указатель не NULL, вы можете быть уверены, что вызов успешен.

Следуя линии, подход, как

  pointer = realloc (pointer, newValue);

проблематично, как и в случае сбоя realloc(), цитата из C11, глава §7.22.3.5,

[....] Если память для нового объекта не может быть выделенный, старый объект не освобожден и его значение не изменилось.

и

Функция realloc возвращает указатель на новый объект (который может иметь тот же значение как указатель на старый объект), или нулевой указатель, если новый объект не может быть выделено.

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

  type tempPOinter = NULL;
  tempPOinter = realloc(oldPointer, newSize);
  if (tempPOinter) {
      oldPointer = tempPOinter;
  }
  else {
     printf("Failure in realloc!!"); 
     free(oldPointer);
     return -1;
  }
...