Ответ 1
В соответствии с man-страницей, если "free" (ptr) уже был вызван раньше, происходит поведение undefined. "
Не нужно взорваться; "не делать ничего" - вполне приемлемое поведение undefined. Также носовые демоны. Не полагайтесь на это.
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!!
Я ошибаюсь где?
В соответствии с man-страницей, если "free" (ptr) уже был вызван раньше, происходит поведение undefined. "
Не нужно взорваться; "не делать ничего" - вполне приемлемое поведение undefined. Также носовые демоны. Не полагайтесь на это.
В вашей программе есть несколько проблем:
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()
указатель более одного раза.
освобождение уже освобожденной памяти приводит к поведению undefined, вам повезло, в этом случае, в другое время вы можете получить свой ядро-дамп
Чтобы добавить к другим ответам, я хотел бы отметить, что если вы установите указатель на NULL, а затем вызвали free(), поведение больше не будет undefined. Это почти не-op. Однако, если указатель освобожден и вы снова вызываете его(), перед назначением указателя в другое место (даже NULL), вы не можете быть уверены в том, что произойдет. Это может привести к дампу ядра в некоторых реализациях, и ничего не произойдет с некоторыми другими.
Это зависит от реализации вашей ОС (linux, windows...), которые реализуют эту функцию. Их поведение может быть различным в зависимости от ОС (поведение undefined), поэтому вы не должны полагаться на них, и вы должны освобождать только одну выделенную память в вашей программе.
EDIT: это не часть ОС, а стандартная библиотека, которая отличается в зависимости от ОС.
Кучное повреждение не должно вызывать проблемы немедленно. Может случиться так, что освобожденная память (или часть памяти) используется для выделения какой-либо другой структуры, а затем может вызвать проблему. free
В памяти больше одного раза всегда UB (undefined) и не должен выполняться, даже если вы не видите злых эффектов в этот момент.
Я ожидал бы, что разработчики DEBUG большинства компиляторов смогут обнаружить этот тип сбоя и сообщить точно, что произошло. Так будет и MSVC.
В RELEASE он может быть оптимизирован для ускорения генерации непредсказуемого поведения.