Перезаписывает ли realloc старое содержимое? - PullRequest
32 голосов
/ 03 октября 2010

Когда мы перераспределяем память через realloc(), предыдущее содержимое перезаписывается?Я пытаюсь создать программу, которая перераспределяет память каждый раз, когда мы вводим в нее данные.

Скажите, пожалуйста, о распределении памяти через realloc, зависит ли это от компилятора, например?

Ответы [ 4 ]

78 голосов
/ 03 октября 2010

Не беспокойтесь о старом содержимом.

Правильный способ использования realloc состоит в том, чтобы использовать специальный указатель для перераспределения, проверить этот указатель и, если все прошло нормально, изменить старый указатель

int *oldpointer = malloc(100);

/* ... */

int *newpointer = realloc(oldpointer, 1000);
if (newpointer == NULL) {
    /* problems!!!!                                 */
    /* tell the user to stop playing DOOM and retry */
    /* or free(oldpointer) and abort, or whatever   */
} else {
    /* everything ok                                                                 */
    /* `newpointer` now points to a new memory block with the contents of oldpointer */
    /* `oldpointer` points to an invalid address                                     */
    oldpointer = newpointer;
    /* oldpointer points to the correct address                                */
    /* the contents at oldpointer have been copied while realloc did its thing */
    /* if the new size is smaller than the old size, some data was lost        */
}

/* ... */

/* don't forget to `free(oldpointer);` at some time */
11 голосов
/ 03 октября 2010

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

9 голосов
/ 03 октября 2010

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

Новая память всегда будет содержатьте же данные, которые присутствовали в старой памяти (хотя они копируются для вас при необходимости), но только до размера старого блока, любое дополнительное пространство, выделенное в конце, будет неинициализировано.

Есливам нужна копия, затем создайте новый malloc и используйте memcpy.

В отношении реализации, когда вы вызываете realloc до увеличения размера, может произойти одно из следующих действий:

  • Новый блок выделяется и содержимое старой памяти копируется, старый блок освобождается, возвращается новый указатель.
  • Если область после блока не выделена, существующий блок можетбыть расширенным и возвращен тот же указатель.

Поскольку у вас нет возможности узнать, что произошло, или даже если реализация полностью отличается отИспользуется предложенное выше, вы всегда должны кодировать в соответствии со спецификацией realloc, то есть вы не должны больше использовать старый указатель и использовать новый.

5 голосов
/ 03 октября 2010

Трудно сказать, что вы спрашиваете, но если вы спрашиваете, можете ли вы прочитать «старое содержимое» по старому адресу, переданному realloc, ответ будет нет . В некоторых случаях вы можете найти часть или все старое содержимое там, но если realloc не вернул тот же указатель, который вы ему передали, любое использование старого указателя будет неопределенное поведение .

Если вы просто спрашиваете, будет ли старое содержимое сохранено по новому адресу, возвращенному realloc, ответ - да (до минимума старого и нового размера).

...