Повреждение памяти

i запускала небольшую программу c:

#include<stdio.h>
int main()
{
char *p;
p = (char *)malloc(10);
free(p);
free(p);
free(p);
printf("\npointer is freed!!\n");
}

В основном я освобождаю память, которая уже освобождена. я думаю, это должно привести к дампу ядра! Это не так?

но он печатает

pointer is freed!!

Я ошибаюсь где?

Ответ 1

В соответствии с man-страницей, если "free" (ptr) уже был вызван раньше, происходит поведение undefined. "

Не нужно взорваться; "не делать ничего" - вполне приемлемое поведение undefined. Также носовые демоны. Не полагайтесь на это.

Ответ 2

В вашей программе есть несколько проблем:

  • Поскольку вы используете malloc() и free(), вы должны сделать #include <stdlib.h> перед вызовом любой из этих функций.
  • Нет необходимости отбрасывать возвращаемое значение из malloc(): он возвращает void *, который можно безопасно назначить любому другому типу указателя (кроме указателей функций). Итак, вы можете сделать: p = malloc(10);
  • Как только вы освободите указатель, выделенный malloc() или realloc(), использование значения указателя каким-либо образом является плохим: в частности, вы не можете снова называть free().
  • int main() лучше записывается как int main(void).
  • Так как main() возвращает int, вы должны вернуть ему значение. Традиционно 0 означает успех.

Конечно, основная проблема (без каламбур) с вашей программой освобождает ее много раз, но важны и другие проблемы, упомянутые выше. Если у вас есть free() 'd указатель успешно, вызов free() в нем - это поведение undefined: программа может делать что угодно, в том числе (к сожалению), похоже, что ничего плохого не делает. Я говорю "к сожалению", потому что это может дать вам ощущение безопасности, что лучше free() указатель более одного раза.

Ответ 3

освобождение уже освобожденной памяти приводит к поведению undefined, вам повезло, в этом случае, в другое время вы можете получить свой ядро-дамп

Ответ 4

Чтобы добавить к другим ответам, я хотел бы отметить, что если вы установите указатель на NULL, а затем вызвали free(), поведение больше не будет undefined. Это почти не-op. Однако, если указатель освобожден и вы снова вызываете его(), перед назначением указателя в другое место (даже NULL), вы не можете быть уверены в том, что произойдет. Это может привести к дампу ядра в некоторых реализациях, и ничего не произойдет с некоторыми другими.

Ответ 5

Это зависит от реализации вашей ОС (linux, windows...), которые реализуют эту функцию. Их поведение может быть различным в зависимости от ОС (поведение undefined), поэтому вы не должны полагаться на них, и вы должны освобождать только одну выделенную память в вашей программе.

EDIT: это не часть ОС, а стандартная библиотека, которая отличается в зависимости от ОС.

Ответ 6

Кучное повреждение не должно вызывать проблемы немедленно. Может случиться так, что освобожденная память (или часть памяти) используется для выделения какой-либо другой структуры, а затем может вызвать проблему. free В памяти больше одного раза всегда UB (undefined) и не должен выполняться, даже если вы не видите злых эффектов в этот момент.

Ответ 7

Я ожидал бы, что разработчики DEBUG большинства компиляторов смогут обнаружить этот тип сбоя и сообщить точно, что произошло. Так будет и MSVC.

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