Programming | 프로그래밍 언어/C++

Dangling Pointer

gyunnnnnn 2022. 11. 19. 17:06

Dangling Pointer ?

  • 적절한 타입의 유효한 객체를 가리키고 있지 않는 포인터이다.
  • 메모리가 해제 된 곳을 가리키고 있는 포인터이다.

발생하는 상황

  • 객체에 대한 참조가 포인터 값에 대한 수정 없이 삭제되거나 할당 해제돼서 포인터가 계속 할당 해제된 메모리를 가리킬 때이다.
  • 기존 프로그램이 Dangling pointer를 역참조하면 메모리는 전혀 다른 데이터를 갖고 있을 것이므로 예측할 수 없는 행동이 발생한다.
  • 포인터가 알려진 상태로 초기화되기 전에 사용될 때 발생한다.
  • 프로그램이 허상 포인터가 가리키는 메모리에 쓰기를 하면 관련되지 않은 데이터의 오염이 발생하게 된다.
  • 리눅스, 유닉스의 경우에는 세그멘테이션 오류가 발생한다.
  • 윈도우의 경우에는 일반 보호 오류가 발생한다.
  • 객체 지향 프로그래밍의 경우 쓰레기 수집으로 허상 참조들은 참조되지 않는 객체를 파괴함으로써 예방된다.
  • 추적이나 참조 횟수 계산 방식에 의해 보증된다.

문제점

  • 메모리 접근 시 예측 불가능한 동작을 일으킬 수 있다.
  • 메모리에 접근이 불가능 하면 Segmentation fault가 발생한다.
  • 보안 위협이 존재 한다.

예제 1

int* ptr = new int(1);
*ptr = 1;
cout << *ptr << endl;

delete ptr;
*ptr = 2;
cout << *ptr << endl;
  • *ptr을 1로 출력하고 메모리를 해제하였지만 할당된 메모리 영역을 가리키고 있다.
  • 이 상황에서 해제된 메모리 영역에 접근하게 되면 댕글링 포인터가 된다.
  • visual studio에서는 *ptr = 2;에서 예외가 발생한다(액세스 위반)

예제 2

int* a = new int(1);
*a = 1;
int* b = a;
cout << *a << " " << *b << endl;

delete a;
cout << *b << endl;
  • 위 상황에서 두번째 b를 출력할때는 b가 댕글링 포인터이기 때문에 쓰레기값을 출력하게 된다.

해결방법

  • 메모리를 해제한 다음에는 포인터를 null로 설정한다.
delete(ptr);
ptr = nullptr;

스마트 포인터

  • 레퍼런스 기반의 스마트 포인터인 WeakPtr, SharedPtr을 사용한다.