Запрос, связанный с free () в C - PullRequest
3 голосов
/ 21 ноября 2011

Что произойдет, если вы попытаетесь освободить память, которая не выделена с помощью malloc/calloc?

Вот что я имею в виду:

void main()
{
int temp = 0;
int *ptr = &temp;
free(ptr);
}

Я думал, free() вернет код ошибки, но free() не имеет возвращаемого значения.

Ответы [ 5 ]

8 голосов
/ 21 ноября 2011

Если вы вызовете free() для указателя, который не был выделен ранее, он вызовет неопределенное поведение.

Из страниц руководства Linux :

Функция free () освобождает пространство памяти, на которое указывает ptr, которое должно быть возвращено предыдущим вызовом malloc (), calloc () или realloc ().В противном случае или, если free (ptr) уже был вызван ранее, происходит неопределенное поведение.Если ptr равен NULL, никакие операции не выполняются.

4 голосов
/ 21 ноября 2011

Добавить к Ответ Малкольма : Это неопределенное поведение по ISO / IEC 9899: 1999, 7.20.3.2:

В противном случае, если аргумент не совпадает с указателем, ранее возвращенным calloc , malloc или realloc функция [...] поведение не определено.

См. Проект стандарта здесь: http://www.open -std.org / jtc1 / sc22 / wg14 / www / docs / n1124.pdf .

2 голосов
/ 21 ноября 2011

Я немного расширил приведенный выше код:

#include <stdio.h>
#include <stdlib.h>

void main()
{
  int temp = 0;
  int *ptr = &temp;
  printf("Before: %0X\n", ptr);
  free(ptr);
  printf("After: %0X\n", ptr);
  getchar();
}

Если этот код скомпилирован Visual Studio 2010, в конфигурации отладки вызов free инициирует сообщение «Ошибка отладки».Это сообщение об ошибке исходит от dbgheap.c:

/*
 * If this ASSERT fails, a bad pointer has been passed in. It may be
 * totally bogus, or it may have been allocated from another heap.
 * The pointer MUST come from the 'local' heap.
 */
_ASSERTE(_CrtIsValidHeapPointer(pUserData));

При компиляции с MinGW-GCC полученный exe-файл запускается без ошибок (строка «After: ...» показывает то же значение для ptr, что и «Before».: ..." линия).

1 голос
/ 22 ноября 2011

Весь ад вырвется на свободу.

Что означает:

  • Если вам повезет, ваша программа выдаст ошибку и завершит работу.
  • Если вам не повезет, какой-то злоумышленник выполнит произвольный код, используяваша программа (free() обычно пытается вставить ваш недавно освобожденный «кусок» памяти в некоторую структуру данных, которая обычно включает в себя некоторые записи в местах, определяемых значениями в / около указателя, который вы передали).
  • Все, что угодномежду этими двумя крайностями.Не завершение по ошибке следует считать хуже, чем завершение по ошибке.
0 голосов
/ 21 ноября 2011

В дополнение к ответам Malcom и undur_gongor, C в Windows с Visual Studio - то же самое. Соответствующий раздел из описания MSDN находится здесь :

Функция free освобождает блок памяти (мембрану), который ранее был выделен вызовом calloc, malloc или realloc. Количество освобожденных байтов эквивалентно количеству байтов, запрошенных, когда блок был выделен (или перераспределен, в случае realloc). Если memblock НЕДЕЙСТВИТЕЛЕН, указатель игнорируется, и освобождение немедленно возвращается. Попытка освободить недопустимый указатель (указатель на блок памяти, который не был выделен calloc, malloc или realloc) может повлиять на последующие запросы выделения и вызвать ошибки.

...