작성
·
317
1
안녕하세요
19분 30초 쯤에 동적할당으로 할당받은 메모리를 free를 통해 반납하는 내용인데요
printf("Before free %p\n", ptr);
free(ptr); // no action occurs when ptr is NULL
printf("After free %p\n", ptr);
위 코드를 실행했을 때 free하기 전 동적할당받은 메모리를 가리키는 포인터 주소와
free한 후의 포인터 주소는 여전히 같음이 나옵니다.
그렇다면 free로 해제를 해도 전에 할당받았던 메모리에 대한 주소를 포인터ptr이 여전히 가지고 있다는 것인데
이렇게 된다면 free가 무색하게 계속 그 메모리에 접근 할 수 있는 거 아닌가요?
물론 free를 함으로써 그 메모리에 대해 할당하고 회수할 컨트롤 권한? 은 os가 다시 가져간다는 것은 이해했지만
약간 명시적인 측면도 있는 건지 궁금합니다.
답변 2
2
안녕하세요, 답변 도우미 Soobak 입니다.
명시적인 측면보다는 free()
함수의 특징 때문으로 이해하시는 것이 옳은 것 같습니다.free()
함수는 메모리 해제를 하되, 포인터 변수 ptr
의 값(즉, 메모리 주소)은 변경하지 않습니다.
free()
함수는 동적으로 할당된 메모리를 해제하는 데에 사요되며, 운영 체제로 하여금 해당 메모리 영역을 프로그램 사용에서 해제하여 다른 용도로 재사용할 수 있도록 합니다.
중요한 점은, free()
함수를 호출한 후에도 포인터 변수 자체는 여전히 원래 메모리 주소를 가리키고 있다는 점입니다.
이 상태에서 포인터는 댕글링 포인터(dangling pointer)
라고 불리며, 메모리 주소를 가리키고는 있지만 프로그램 사용으로부터 해제된 부분이기 때문에 안전하게 사용할 수 없습니다.
이미 해당 메모리 영역이 다른 용도로 사용되고 있을 수 있기 때문입니다.
따라서, free()
를 사용한 후에는 해당 포인터를 NULL
로 설정하는 것이 일반적인 안전한 프로그래밍 관행입니다.
이렇게 하면, 포인터가 이미 해제된 메모리를 가리키고 있는지 여부를 쉽게 확인할 수 있으며, 실수로 해제된 메모리에 접근하는 것을 방지할 수 있습니다.
이 부분이 말씀하신 '명시적인 측면'과 관련이 있습니다.
추가적으로, '댕글링 포인터'
,'dangling pointer'
의 키워드로 검색을 해보시면 자세한 학습에 도움이 되실 것 같습니다.
1
안녕하세요, 인프런 AI 인턴입니다.
Echapper4님의 질문은 C언어에서 free
함수 사용 후에 포인터가 여전히 원래 메모리 주소를 가지는 이유와 free
후에 메모리 접근 가능성에 대한 궁금증을 담고 있습니다.
비슷한 내용을 다룬 기존의 답변으로는 “free()함수의 정확한 용법 ( realloc함수와 free함수의 관계)“라는 제목의 게시글이 해당될 수 있습니다. 해당 답변에서는 free
함수가 메모리를 운영체제에 반환하는 것이라 설명하며, 반환된 후에도 메모리 주소가 여전히 남아있을 수 있지만, 이것은 더 이상 안전하게 접근할 수 있는 주소가 아니라는 점을 설명하고 있습니다. free
후에 포인터를 다시 사용하는 것은 용납되지 않으며, 실질적인 메모리 접근 권한은 운영체제에 의해 결정된다는 내용입니다.
해당 답변은 여기서 확인할 수 있습니다: free()함수의 정확한 용법 ( realloc함수와 free함수의 관계)
free가 수행된 후 포인터 주소가 변경되지 않는 이유에 대해서는 홍정모 강사님께서 충분히 설명하고 계십니다. free
는 메모리가 운영체제에 반환되었음을 의미하지만, 포인터 변수 자체의 값인 주소가 당장 변경되지는 않습니다. 또한 free
된 메모리에 접근하는 행위는 무단 접근이 되며, 이는 정의되지 않은 행동(Undefined Behavior)으로 이어질 수 있어서 피해야 합니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
다른 분들이 보시기를 고대하며..
그렇다면 free를 한 이상
프로그래머는 그 할당됐었던 메모리가 다른 데에서 다시 쓰이기 시작해서 다른 데이터로 덮어씌여졌는지 알 수 없으며
운이 좋으면 기존의 남아있던 데이터를 사용할 수 있지만
불안정한 영역이니 절대사용치 않는 것이 적절하다는 것이 괜찮은 이해인지 궁금합니다.
(그래서 후에 ptr = NULL로 그 경우를 미연에 막는 것 인가 싶기도 합니다.)
안녕하세요, 답변 도우미 Soobak 입니다.
말씀하신 내용이 맞습니다.
정확히 잘 이해하고 계십니다.
운영 체제는 해제된 메모리 영역을 언제든지 다른 목적으로 재사용할 수 있으며, 이때 기존 데이터는 새로운 데이터로 덮어쓰여질 수 있습니다.
이는 참고 답변 링크에서 교수님께서 설명해주시듯, 프로그래머가 예측하거나 제어할 수 없는 부분입니다.
따라서, 말씀하시는 것처럼 불안정한 메모리 영역이므로, ptr = NULL;
을 통해 해당 포인터가 더 이상 유효한 메모리를 가리키지 않음을 명시적으로 나타내며, 실수로 해당 포인터를 사용하는 것을 방지할 수 있습니다.
NULL
포인터에 접근하려고 하면 프로그램은 일반적으로 즉시 오류를 발생시키므로, 이를 쉽게 감지하고 디버깅할 수 있습니다.
감사합니다 !!