1. 원시 포인터 및 연산자
C+의 원시 포인터는 메모리 주소를 직접 보유하는 저수준 언어이다.
메모리를 수동으로 할당하고, 동적 배열을 생성하고, 값을 효율적으로 전달하는 데 사용할 수 있다.
1. new 연산자
연산자는 힙에 메모리를 할당하는 데 사용된다.
할당된 메모리는 해당 연산자를 사용하여 명시적으로 할당을 취소할 때까지 사용 가능한 상태로 유지된다.
예시
2. delete 연산자
delete 연산자는 할당된 메모리의 할당을 취소하는 데 사용된다.
메모리 할당이 취소된 후에도 다른 용도로 다시 할당할 수 있으며, 메모리 할당을 제대로 해제하지 못하면 메모리 누수가 발생할 수 있다.
3. new[ ] 및 delete[ ]
연산자는 객체 배열에 대한 메모리 할당 및 할당 해제에 사용된다.
2. 메모리 누수(Memory Leak)
메모리 누수는 프로그램이 힙에 메모리를 할당하지만 더 이상 필요하지 않을 때 메모리를 운영 체제로 다시 해제하지 않을 때 발생한다.
이로 인해 시간이 지남에 따라 사용 가능한 메모리가 고갈되어 시스템 성능이 저하되거나 충돌이 발생한다.
C++에서 원시 포인터를 사용하는 경우 메모리 할당 및 할당 취소를 수동으로 관리해야 한다.
대부분의 경우 키워드를 사용하여 힙의 객체에 대한 메모리를 할당하고 더 이상 필요하지 않을 때 키워드를 사용하여
해당 메모리의 할당을 취소합니다. 이 작업을 잊어버리면 메모리 누수가 발생할 수 있다. +
메모리 누수를 방지하려면 포인터가 범위를 벗어나거나 다시 할당되기 전에 항상 메모리의 할당이 취소되었는지 확인해야 한다.
이를 달성하는 몇가지 방법에는 C++ 스마트 포인터 , RAII(Resource Acquisition Is Initialization) 기술 및 내부적으로
메모리 할당을 관리하는 컨테이너를 사용하는 것이 포함된다.
unique_ptr, shared_ptr, vector, string
3. 스마트 포인터
1. 고유 포인터(Unique_ptr)
unique_ptr는 C++ 표준 라이브러리에서 제공하는 스마트 포인터 이다.
단일 객체 또는 배열을 관리하는 데 사용되는 템플릿 클래스이다.
unique_ptr 배타적 소유권(Exclusive Ownership)의 개념에 따라 작동하며, 이는 한 번에 한 명만 객체를 소유 할 수 있다.
이 소유권을 이전하거나 이동할 수 있지만 공유하거나 복사는 불가능 하다.
이 개념은 dangling pointer(삭제 또는 해제된 메모리를 가리키는 포인터)와 같은 문제를 방지하고,
메모리 누수를 줄이고, 수동 메모리 관리의 필요성을 제거하는 데 도움이 된다.
범위를 벗어나면 소유한 객체가 자동으로 삭제된다.
소유권 이전 방법
사용자 지정 삭제와 함께 unique_ptr 사용
unique_ptr은 배타적 소유권을 가지고 있기 때문에 객체에 대한 공유 액세스가 필요한 경우 사용할 수 없다.
2. 공유 포인터(Shared Pointer)
A는 여러 포인터가 동적으로 할당된 객체의 소유권을 공유할 수 있도록 하는 C++의 스마트 포인터 유형이다.
객체를 가리키는 마지막 객체가 소멸되는 경우에만 자동으로 할당이 취소된다.
shared_ptr를 사용하는 경우 참조 카운터는 새 포인터가 만들어질 때마다 자동으로 증가하고
각 포인터가 범위를 벗어나면 감소한다.
참조 카운터가 0에 도달하면 시스템이 메모리를 정리한다.
동일한 객체의 소유권을 공유하며, 객체는 두 포인터가 모두 범위를 벗어나고 참조 카운터가 0이 될 때마다
소멸된다.
3. 약한 참조 포인터(Weak Pointer)
weak_ptr은 C++에서 제공하는 스마트 포인터의 한 종류로, 직접 객체를 소유하지 않으면서도
객체에 대한 참조를 유지하는 포인터이다. 이를 통해 순환 참조(Circular reference)를 해결할 수 있다.
weak_ptr은 객체의 참조 횟수를 증가시키지 않는다.
shared_ptr은 객체를 소유하고 있으며, 참조 횟수를 증가 시키지만 weak_ptr은 그렇지 않으며
객체의 생명주기에 영향을 주지 않는다
또한 shared_ptr 간의 순환 참조를 방지하는 기능이 있다.
만약 두 개의 객체가 서로 shared_ptr을 통해 참조하고 있다면, 두 객체가 모두 소멸되지 않는 문제가 발생할 수 있다.
weak_ptr을 사용하면 한쪽에서 객체의 생명 주기에 영향을 주지 않으면서 참조만 유지할 수 있다.
C++의 스마트 포인터는 컨트롤 블록(Control block)을 사용하여 참조 횟수를 관리하는 기능이 있다
컨트롤 블록에는 두가지의 참조 횟수가 있는데
1. 소유권 참조 횟수(Ownership count) -> shared_ptr의 개수
2. 약한 참조 횟수 -> weak_ptr의 개수
weak_ptr이 아무리 많아도 객체는 shared_ptr이 모두 소멸될 때 삭제된다.
그러나 컨트롤 블록은 shared_ptr과 weak_ptr이 모두 해제될 때 삭제가 된다.
weak_ptr을 사용하려면 lock()을 호출하여 shared_ptr로 변환을 시켜주고
weak_ptr은 객체를 직접 접근할 수 없고, 먼저 lock()을 호출하려 shared_ptr로 변환 후 사용해야 한다.
lock()을 호출했을 때, 대상 객체가 이미 소멸되었다면 nullptr을 반환하여 준다.
참고 자료 : C++ 개발자 로드맵
C++ Developer Roadmap
Community driven, articles, resources, guides, interview questions, quizzes for C++ development. Learn to become a modern C++ developer by following the steps, skills, resources and guides listed in this roadmap.
roadmap.sh
포인터 및 참조
'C++ Practice' 카테고리의 다른 글
Study C++ Developer RoadMap (5) (0) | 2025.02.25 |
---|---|
Study C++ Developer RoadMap (4) (0) | 2025.02.19 |
Study C++ Developer RoadMap (2) (0) | 2025.02.17 |
Study C++ Developer RoadMap (1) (0) | 2025.02.12 |
Set Library C++ (3) | 2024.11.12 |