Search
Duplicate

[C] 댕글링 포인터 - free한 뒤에 NULL을 할당하는 이유

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C
Scrap
태그
9 more properties
free한 뒤에 NULL을 할당하지 않으면 댕글링 포인터 문제가 생긴다.

댕글링 포인터(Dangling Pointer, premature free)란?

적절한 타입의 유효한 객체를 가리키고 있지 않은 포인터. 예를 들어 어떤 포인터가 이미 할당 해제된 메모리를 포인터가 계속 가리키고 있다면 그 포인터를 댕글링 포인터라고 한다.

문제

메모리 접근시 예측 불가능한 동작
메모리 접근 불가 시 Segmentation fault
잠재적인 보안 위험

원인

메모리 해제 후, 해제된 메모리에 접근
함수 호출에서 자동 변수를 가리키는 포인터의 반환

free()만 사용할 때 문제점과 해결 방법

#include <stdlib.h> #include <string.h> #include <stdio.h> char *ft() { //1. malloc char *ptr; ptr = (char *)malloc(sizeof(char) * 10); ptr = strcpy(ptr, "hello"); printf("%p\n", ptr); //0x7fc519405820 printf("%s\n", ptr); //hello //2. free free(ptr); //ptr은 댕글링 포인터가 된다. ptr = strcpy(ptr, "bye"); return(ptr); } int main() { char *ptr; ptr = ft(); printf("return: %p\n",ptr); //return: 0x7fca65c05820 printf("return: %s\n",ptr); //return: hello //return: bye return (0); }
C
복사
Q. 의문점: free해도 포인터의 값을 변경하거나 return하는 것이 가능하다.
A. free()는 malloc()사용시 메모리 공간을 재사용할 수 있게 만들어줄 뿐, 해당 메모리에 있는 값에 대해 어떠한 처리를 해주지는 않는다.
c표준 free 정의
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation.
free함수는 ptr이 가리키는 공간을 할당 취소한다. 즉, 해당 공간을 추가 할당에 사용할 수 있게 만든다.
이는 이후에 malloc() 등으로 해당 공간을 호출할 때 동일한 메모리 공간을 재사용할 수 있게 만들었음을 의미한다. 포인터가 free()에 전달되는 즉시 포인터가 가리키는 객체는 수명을 다하게 된다. 포인터가 가리키는 객체를 참조하려는 시도를 하면 정의되지않은 동작이 발생한다. (즉, 더이상 포인터를 역참조할 수 없음)
free()의 인수는 (모든 C 함수 인자와 마찬가지로) 값으로 전달되므로 실제로 포인터를 수정할 수는 없다. 포인터는 (해당 공간의) 호출 전과 후에 동일한 값을 가지지만, 그 값은 호출 전에는 유효하고 호출 후에는 불확실하다.
포인터 값을 참조하거나 역참조하려할 때 그것이 작동하는 것처럼 보일 수도 있다. 그러나 이는 정의되지 않은 동작의 여러 가지 가능한 증상 중 하나이므로 오류를 감지하고 진단하기 어렵게 만드는 최악의 오류다.
결론: 위의 오류를 예방하기 위해 free한 후 NULL을 해주는 것이 좋다!
#include <stdlib.h> #include <string.h> #include <stdio.h> char *ft() { //1. malloc char *ptr; ptr = (char *)malloc(sizeof(char) * 10); ptr = strcpy(ptr, "hello"); printf("%p\n", ptr); //0x7fc519405820 printf("%s\n", ptr); //hello //2. free free(ptr); //ptr은 댕글링 포인터가 된다. //3. NULL ptr = NULL; return(ptr); } int main() { char *ptr; ptr = ft(); printf("return: %p\n",ptr); //return: 0x0 printf("return: %s\n",ptr); //return: (null) return (0); }
C
복사
참조
NULL을 할당하는 방법 외에 댕글링 포인터를 관리할 수 있는 방법은 아래 링크 참조