int main()
{
int *ptr, **ptr1;
ptr = (int*)malloc(sizeof(int));
ptr1 = (int**)malloc(sizeof(int));
free(ptr);
*ptr = 12345;
ptr1 = &ptr;
//free(ptr);
//**ptr1 = 23456;
printf("%d \n", **ptr1);
system("pause");
return 0;
}
Как *ptr
сохранить значение 12345
когда память уже была freed
? А сейчас ptr
должен указывать на garbage
,
Почему это происходит?
Этот код очень ошибочен на многих уровнях.
malloc()
в С.ptr1
потребности sizeof *ptr1
не sizeof (int)
, Это указатель!malloc()
может потерпеть неудачу. Проверьте возвращаемое значение перед использованием.free()
д это. Неопределенное поведение.Также обратите внимание, что сам указатель не разрушается при звонке free()
в теме; вещь, которая уходит, — это память, на которую ссылается указатель. Таким образом, вы можете хранить биты указателя в самом указателе, если хотите. Однако в редких случаях это необходимо, и следует проявлять осторожность, когда / если вы проверяете биты.
Указатель освобождается, но он все еще указывает, куда бы он ни делался, когда был выделен. Для этого считается серьезной ошибкой программирования. Но среда выполнения (обычно) не помогает выявлять или исправлять такие ошибки.
Не направляйте пистолет на себя и не нажимайте на курок!
Это неопределенное поведение, все может случиться.
free(ptr);
*ptr = 12345;
Незаконно Это может привести к сбою или, если вам не повезло, может сработать, потенциально скрывая проблему, пока программное обеспечение не будет отправлено на атомную электростанцию. Хотя, если вы пишете такой код, вы, вероятно, не работаете в таких компаниях. 🙂
Вы, кажется, не понимаете неопределенного поведения. В основном, поведение не определено. Это может сделать что угодно, включая (но не ограничиваясь) следующее:
Доступ к освобожденной памяти в целом, вероятно, (на большинстве систем) выглядит так, как если бы он работал, в то время как случайное повреждение данных, которые, по мнению какой-либо другой части программы, принадлежат ей (зависит от того, было ли выделение после освобождения).
Попытка определить неопределенное поведение ставит вас в тупик. Гораздо лучше просто не делать это в первую очередь.
free () освобождает память, указанную * ptr, но не изменяет значение * ptr, поэтому, если это значение не конфликтует ни с чем другим, оно все равно будет работать, но память может быть выделена другим процессом случайным образом. Обычная практика — делать бесплатно (ptr); ptr = NULL, чтобы избежать случайного повторного использования памяти без другого вызова malloc.