실제로 삽입 된 요소 수에 필요한 최소한의 메모리보다 많은 메모리를 할당하는 모든 종류의 데이터 구조 (즉, 한 번에 하나의 노드를 할당하는 링크 된 구조 이외의 것)를 구현해야합니다.
테이크 컨테이너 좋아 unordered_map
, vector
또는 deque
. 이들은 모두 단일 삽입마다 힙 할당이 필요하지 않도록 지금까지 삽입 한 요소에 필요한 최소 메모리보다 많은 메모리를 할당합니다. vector
가장 간단한 예로 사용합시다 .
할 때 :
vector<Foo> vec;
// Allocate memory for a thousand Foos:
vec.reserve(1000);
... 실제로 수천 개의 Foos를 구성하지는 않습니다. 단순히 메모리를 할당 / 예약합니다. 경우 vector
여기에 새로운 배치를 사용하지 않은, 그것은 기본적으로 건설 될 것이다 Foos
사방을뿐만 아니라 심지어 당신도 처음에 삽입되지 않습니다 요소에 대한 소멸자를 호출 할 필요.
할당! = 건설, 해방! = 파괴
일반적으로 위와 같은 많은 데이터 구조를 구현하기 위해 말하면 메모리 할당 및 요소 생성을 하나의 불가분의 것으로 취급 할 수 없으며, 메모리 해제 및 요소 삭제를 하나의 불가분의 것으로 취급 할 수 없습니다.
생성자와 소멸자를 불필요하게 좌우로 호출하는 것을 피하기 위해 이러한 아이디어 사이에 분리가 있어야합니다. 그래서 표준 라이브러리는 std::allocator
(메모리를 할당 / 해제 할 때 요소를 구성하거나 파괴하지 않습니다 *) 에서 아이디어를 분리합니다. 배치를 사용하여 요소를 수동으로 구성하고 소멸자를 명시 적으로 호출하여 요소를 수동으로 파괴하는 컨테이너를 사용하는 컨테이너.
- 나는 디자인이 싫지만
std::allocator
그것이 도망 치지 않을 다른 주제입니다. :-디
어쨌든, 기존 컨테이너로 만들 수 없었던 많은 범용 표준 호환 C ++ 컨테이너를 작성했기 때문에 많이 사용하는 경향이 있습니다. 그중에는 일반적인 경우 힙 할당을 피하기 위해 수십 년 전에 구축 한 작은 벡터 구현과 메모리 효율적인 트리 (한 번에 한 노드를 할당하지 않음)가 포함됩니다. 두 경우 모두 기존 컨테이너를 사용하여 실제로 구현할 수 없었기 때문에 placement new
불필요한 왼쪽과 오른쪽에 생성자와 소멸자를 불필요하게 호출하는 것을 피해야했습니다.
당연히 사용자 지정 할당 자와 함께 사용하여 자유 목록과 같이 개별적으로 객체를 할당하는 경우 일반적으로 다음 placement new
과 같이을 사용하고 싶을 것입니다 (예외 안전 또는 RAII를 방해하지 않는 기본 예).
Foo* foo = new(free_list.allocate()) Foo(...);
...
foo->~Foo();
free_list.free(foo);