[C++ Core] 상수 구문 - new
연산자
자유 영역
변수들은 모두 각자만의 유효범위(scope)와 수명주기(lifetime)가 존재한다. 지역 변수인 경우에는 선언된 유효범위를 벗어나게 되면 자동으로 없어진다. 하지만, 간혹 유효범위와 독립적으로 존재하는 변수들이 유용할 때가 있다. 가령 함수 안에 있는 객체를 반환하는 경우말이다. 그런 변수들은 스택 대신 자유 영역(free store)에 존재하며 이 영역은 힙(heap), 동적 메모리(dynamic memory)라고도 불린다. 자유 영역에 존재하는 변수를 만드려면 new
와 delete
연산자를 사용하면 된다.
// C11 : 중괄호 초기자를 통해 초기화를 할 수 있다. int* ip = new int{ 2 }; // new[]를 이용하면 연속된 메모리 영역을 할당할 수 있다. int* ip2 = new int[5]{ 1, 2, 3, 4, 5 }; // 메모리는 자원이기 때문에 사용이 끝나면 반환해줘야 한다. // new와 delete, new[]와 delete[] 쌍은 꼭 맞춰야 한다. delete ip; delete[] ip2; // 메모리를 반환해주고 나면 포인터는 유효하지 않은 곳을 가리키게 된다. // 이를 댕글링 포인터(dangling pointer)라 한다. // 이중 삭제를 방지하기 위해 nullptr로 할당하는 경우도 있다. ip = ip2 = nullptr; // nullptr에 delete를 해도 아무런 효과가 일어나지 않는다. delete ip;
자유 영역 연산자는 모두 <new>
헤더에 존재하며, 연산자 오버로딩이 가능하다. new
연산자의 시그너처가 궁금하다면 여기를 방문해보자. delete
연산자는 여기에서 볼 수 있다. 생각보다 많은 수에 놀랄지도 모르겠으나 크게 보면 (1)일반적으로 사용하는 new
(2)nothrow new
그리고 (3)위치지정 new
로 나눌 수 있다. 1번은 많이 사용하는 것이고, 자주 접한 것이니 2번과 3번을 자세히 살펴보자.
nothrow new
new
연산자는 메모리 할당 시 메모리가 부족하면 std::bad_alloc
예외를 내뱉는다. 예외 처리는 성능을 꽤 잡아먹기에, 성능이 중요한 프로그램에서는 달갑진 않을 것이다. 이럴 때 nothrow new
를 사용할 수 있다. nothrow new
는 이름처럼 예외 대신 nullptr
을 반환한다.
SomeHeavyType* p = new(std::nothrow) SomeHeavyType; if (p) { // do something }
위치지정 new
new
를 이용하면 간편하게 자유 영역에 존재하는 변수를 만들 수 있다. 그러나, 메모리 파편화가 발생할 수 있고, 자주 메모리 할당이 일어나는 프로그램이라면 메모리 사용량을 분석하여 한번에 할당을 해놓고 스택처럼 사용하는 것이 성능 향상에 도움을 줄 것이다. 이를 위해 위치지정 new
를 사용할 수 있다.
using byte = unsigned char; class A; // allocate byte* memory = new byte[10000]; A* pA = new(memory) A; // do something // delete // 위치지정 delete도 물론 있지만 아무것도 수행하지 않는다. // ex: delete(pA, memory); pA->~A(); // 소멸자를 호출하는 것이 중요하다. delete[] memory;
이를 기반으로 한 메모리풀(memory pool)이라는 자료구조도 존재한다. 메모리풀은 다음에 기회가 되면 소개하도록 하겠다.
'Outdated > Core Language' 카테고리의 다른 글
[C++ Core] 함수 개체(function object)와 람다 표현식(lambda expression) (0) | 2018.09.07 |
---|---|
[C++ Core] 상수 구문 - const vs constexpr (0) | 2018.08.21 |
[C++ Core] POD(plain old data), 표준 레이아웃 타입(standard layout type), 간단한 타입(trivial type) (0) | 2018.08.17 |
[C++ Core] 우측 값 레퍼런스(rvalue reference) (4) | 2018.08.15 |
[C++ Core] 타입 추론(type deduction) - auto와 decltype (0) | 2018.08.13 |