C++/개념정리

C++[Dangling Pointer, Double Free, 스마트 포인터]

jeongchanhyo 2024. 12. 30. 20:03

Dangling Pointer

메모리에서 더 이상 유효하지 않은 주소를 가리키고 있는 포인터를 의미한다.

포인터는 주소를 참조하는데 그 주소에 있는 메모리가 해제됐을 때 실행을 하면 프로그램에 심각한 문제를 일으킬 수 있다.

주요 발생 원인

  • 함수가 종료된 후, 그 함수의 지역 변수를 가리키는 포인터가 남아 있을 때.
  • 동적 메모리 해제 후 그 메모리 주소를 가리키는 포인터가 남아 있을 때.
  • 객체가 소멸한 후, 그 객체의 주소를 가리키는 포인터가 남아 있을 때.

나올 수 있는 문제점

  • Dangling Pointer를 통해 접근할 경우, 프로그램이 예기치 않게 동작할 수 있다.
  • 잘못된 메모리 접근으로 인해 다른 변수나 데이터가 손상될 수 있다.
  • 접근 권한이 없는 메모리를 참조하면 프로그램 충돌이 일어날 수 있다.

Double Free

Double Free는 메모리 이중 해지라고 불리는데, 이미 해제된 데이터를 한 번 더 해제하려고 할 때 발생하는 오류다.

주요 발생 원인

  • 같은 포인터를 두 번 호출하여 메모리를 해제할 때
  • 여러 포인터가 같은 메모리 블록을 가리킬 때, 하나의 포인터가 메모리를 해제해도 여전히 그 메모리를 해제할 수 있음.
  • 함수 안에서 메모리가 해제됐는데 다른곳(메인 함수 등)에서 그 포인터를 다시 사용하려고 할 때

나올 수 있는 문제점

  • 이중 해지로 인해 프로그램이 예기치 않게 동작할 수 있습니다.
  • 메모리 관리자가 이미 해제된 메모리를 참조하려고 하면 프로그램 충돌이 일어날 수 있다.
  • 이중 해지는 보안 취약점을 초래할 수 있으며, 악의적인 코드 실행을 유발할 수 있다.

스마트 포인터

늘 이런 위험부담을 안고 프로그래밍을 할 수는 없으니 만든 보호책이 스마트 포인터다.

 

스마트 포인터는 메모리 관리의 안전성을 높이고, 메모리 누수나 이중 해지와 같은 문제를 방지하기 위해 사용되는 객체다. C++11부터 도입된 스마트 포인터는 메모리를 자동으로 관리하여 프로그래머의 부담을 줄여준다. 주요 스마트 포인터에는 std::unique_ptr, std::shared_ptr, std::weak_ptr가 있다. 밑의 설명에서는 std는 생략하겠다.

1. unique_ptr

소유권이 독점적인 포인터이다. unique_ptr만 해당 메모리를 소유할 수 있고 다른애들은 그 주소에 있는 메모리를 가져다 쓸 수없게된다. 이렇게 관리해서 특정 메모리를 안전하게 생성하고 제거할 수 있다.하지만 소유권을 다른 unique_ptr로 이동할 수는 있다. 소유권을 이동할 때는 std::move를 사용한다.

예시

unique_ptr의 내부 포인터에 접근하려면 get() 메서드를 사용하여 주소를 얻을 수 있습니다. 하지만 이 경우에도 메모리 소유권은 여전히 unique_ptr에 있어 변경시키거나 파괴할 수 없다.

ex) int* rawPtr = ptr.get();// 이걸하면 그 주소를 가져옴, 하지만 영향을 끼칠수는 없다.

2.shared_ptr

여러개의 포인터가 동일한 메모리를 공유하는 포인터이다. 메모리는 마지막 포인터가 사라질 때 자동으로 해제가 되어서 Dangling Pointer을 예방하는 아주 훌륭한 예방책이다.

3. weak_ptr

weak_ptr은 shared_ptr과 함께 사용되고 메모리에 대해 약한 참조를 제공한다.

shared_ptr과는 엄연히 다르기 때문에 참조 카운트에 포함되지 않는다.

shared_ptr을 사용해서 두개 이상의 포인터가 꼬리물기로 서로를 참조할 때 순환참조의 문제가 발생해 메모리가 해제되지 않는 문제가 생기는데 이러한 순환 참조를 방지하는데 사용된다.

weak_ptr은 share_ptr로 변환이 가능하며 이 때 객체가 유효한 경우에만 변환이 되기 때문에 Dangling Pointer예방도 가능하다.

끝!

'C++ > 개념정리' 카테고리의 다른 글

C++[함수 오버로딩]  (0) 2024.12.31
C++[얕은 복사, 깊은 복사]  (0) 2024.12.30
C++[스택 메모리, 힙 메모리]  (0) 2024.12.30
C++[상속, 다형성]  (0) 2024.12.26
C++[헤더파일, 파일관리]  (0) 2024.12.26