Program Tip

C ++에서 new 대신 std :: allocator를 사용하는 이점은 무엇입니까?

programtip 2020. 12. 7. 20:34
반응형

C ++에서 new 대신 std :: allocator를 사용하는 이점은 무엇입니까?


에 대해 읽었습니다 std::allocator. 제 생각에는 new을 사용하는 대신 사용하는 것이 더 복잡합니다 delete.

allocator우리가 명시 적으로 힙 메모리를 할당해야합니다, 그것을 구성을 파괴하고 마지막으로 메모리를 할당 해제. 그렇다면 왜 만들어 졌습니까?

어떤 경우에 사용할 수 있으며 new 및 delete 대신 언제 사용해야합니까?


std::allocator표준 라이브러리 컨테이너의 기본 메모리 할당 자이며 자신의 할당자를 대체 할 수 있습니다. 이를 통해 표준 컨테이너가 메모리를 할당하는 방법을 제어 할 수 있습니다. 그러나 나는 당신의 질문이 std::allocator구체적으로 말하는 것이 아니라 new T[N], 예를 들어를 사용하는 것보다 메모리를 할당 한 다음 그 메모리에서 객체를 구성하는 전략 이라고 생각합니다 .

그 이유는 new T[N]생성자가 호출되는 것을 제어 할 수 없기 때문입니다 . 그리고 동시에 모든 개체를 구성해야합니다. 이것은 예를 들어 std::vector가끔씩 만 할당하려는 목적으로 끔찍합니다 .

원시 메모리 할당자를 사용하면 용량을 결정하는 일정량의 메모리를 할당 할 수 있습니다. 그런 다음 사용자가 선택한 생성자를 사용하여 벡터에 항목을 추가하면이 메모리에 개체를 구성 할 수 있습니다.

그런 다음 메모리가 부족하면 일반적으로 두 배 더 많이 할당합니다. std::vector사용 new T[N]하면 요소를 추가하거나 제거 할 때마다 재 할당해야하므로 성능이 좋지 않습니다. 또한 모든 객체에 대해 기본 생성자를 사용해야하므로 std::vector보유 할 수있는 객체 유형에 불필요한 제한 이 있습니다.


제 생각에는 new와 delete를 사용하는 대신 사용하는 것이 더 복잡합니다.

네,하지만 그것을 대체하는 것은 아닙니다 newdelete는 다른 용도로 사용됩니다.

할당자를 사용하여 명시 적으로 힙 메모리를 할당하고 구성하고 파괴 한 다음 마지막으로 메모리 할당을 해제해야합니다.

그렇다면 왜 만들어 졌습니까?

때로는 할당과 구성을 두 단계로 분리하고 싶기 때문입니다 (파괴 및 할당 해제를 두 단계로 분리하는 것과 유사). 그렇게하고 싶지 않다면 할당자를 사용 new하지 말고 대신 사용하십시오.

어떤 경우에 사용할 수 있으며 new 및 delete 대신 언제 사용해야합니까?

new의 동작이 아닌 할당 자의 동작이 필요할 때 delete분명히! 일반적인 경우는 컨테이너를 구현할 때입니다.

다음 코드를 고려하십시오.

std::vector<X> v;
v.reserve(4);        // (1)
v.push_back( X{} );  // (2)
v.push_back( X{} );  // (3)
v.clear();           // (4)

여기 줄 (1)은 4 개의 객체에 충분한 메모리를 할당해야하지만 아직 구성하지는 않습니다. 그런 다음 줄 (2)와 (3)은 할당 된 메모리에 개체를 구성해야합니다. 그런 다음 줄 (4)는 해당 개체를 삭제해야하지만 메모리 할당을 해제해서는 안됩니다. 마지막으로 벡터의 소멸자에서 모든 메모리를 할당 해제 할 수 있습니다.

따라서 벡터는 객체를 사용 new X()하거나 delete &m_data[1]생성 및 파괴 할 수 없으며 생성 / 파괴와 별도로 할당 / 할당을 수행해야합니다. 컨테이너의 할당 자 템플릿 인수는 메모리 할당 (해제) 및 객체 생성 / 파괴에 사용되어야하는 정책을 정의하여 컨테이너의 메모리 사용을 사용자 정의 할 수 있도록합니다. 기본 정책은 std::allocator유형입니다.

따라서 할당자가 필요할 때 (예 : 컨테이너를 사용할 std::allocator) 할당자를 사용하고 사용자 지정 할당자를 제공하지 않고 표준 할당자를 원할 때 사용합니다.

new및에 대한 대체물로 할당자를 사용하지 않습니다 delete.


할당자는 STL에서 매우 중요한 개념입니다. 모든 컨테이너는 할당자를 인수로 사용할 수 있습니다. 그런 다음 할당은 표준 할당자가 아닌이 할당자를 사용하여 수행됩니다.

이는 예를 들어 풀에 같은 크기의 객체를 할당하거나 성능을 향상시키는 데 유용하거나 객체가 살아야하는 특별한 메모리 영역이있는 경우 필요할 수 있습니다.

할당 및 구성 단계는 분리되어 있습니다. 예를 들어 벡터 ( std::vector::reserve)의 경우 향후 사용을 위해 메모리를 할당 할 수 있어야하지만 (아직) 그 안에 객체를 생성하지 않는 것이 중요하기 때문입니다.

AS를 예를 들어 당신은 고정 된 크기의 배열을 포함하는 클래스로 할당자를 쓰고, 어떤 표준 컨테이너의 메모리를 제공하기 위해 해당 배열을 사용할 수 있습니다. 그런 다음 스택에 해당 클래스의 인스턴스를 가질 수 있으므로 프로그램의 일부에 대한 힙 할당을 완전히 피할 수 있습니다.

이 SO 게시물에서 더 많은 예제를 참조하십시오.

[...] 언제 사용해야 [...]

특정 요구 사항이있을 때, 고유 한 일반 컨테이너를 작성할 때 가장 중요합니다.


본능이 맞습니다. 90 %의 경우 new. 그러나 데이터 구조 와 같은 구조에서 주목하십시오 . 기본 템플릿 인수 중 하나는 class Alloc = allocator<pair<const Key,T>클래스가 사물의 새 인스턴스를 만들고 기존 인스턴스를 관리하는 방법을 정의하는입니다. 이런 식으로 이론적으로 자신의 할당자를 만든 다음 기존 데이터 구조에 사용할 수 있습니다. 이후 newdelete기능이 아니라 클래스입니다,이 필요하다 std::allocator그들을 대표하고 그들에게 유효한 템플릿 인수를 만들 수 있습니다.


std::allocator개발자들에게 메모리가 할당되는 방법을 더 제어 할 수 있도록하기 위해 만들어졌습니다. 많은 임베디드 시스템에서 메모리는 제한적이고 다른 유형입니다. 엄청난 양이 없을 수도 있습니다. 또한 조각화 문제를 방지하기 위해 메모리 할당을 최소화하려고합니다.

할당자는 또한 다른 메모리 풀에서의 할당을 허용합니다. 예를 들어, 작은 크기의 블록을 할당하는 것은 작은 블록 메모리 풀에서 더 효율적입니다.


newdelete동적 메모리에서 객체를 생성하고 초기화하기위한 직접적인 방법이다. 할당자는 앞서 언급 한 단계를 완벽하게 제어 할 수 있기 때문에 훨씬 더 많습니다.

할당자를 사용하여 명시 적으로 힙 메모리를 할당하고 구성하고 파괴 한 다음 마지막으로 메모리 할당을 해제해야합니다.

Indeed allocators are not supposed to be used for "normal" code where new and delete would equally be fine. Consider a class like std::map, often implemented as a tree: do you need to deallocate the whole leaf whenever an object held is deleted? Allocators allow you do destruct that object, but keep the memory so that you don't have to require it again.

Further, you may specialize an allocator for a certain type if you know more optimized methods for its control which is not possible for new and delete.


The reason for this STL member is to give the developer more control over memory. What I mean by this is, for instance, the new operator is not really just one operation per se. At its most basic, it performs a reservation of memory AND then fills that space with the object.

Although I cannot on top of my head come up with a specific, real-world case scenario, you should use std::allocator and such when, perhaps, the destruction of a given object might impact other objects in memory.

Let's say, for the sake of argument, you created some kind of vector which each element is double-linked to some other object in memory and you want, at the time of deletion of said vector, the objects linked to remove the reference back to it.


You are confused. std::allocator calls/uses new and delete. It is simply another level in the C++ memory hierarchy, used to serve the various needs of the C++ standard library, particularly the containers, but other types too. The C++ library containers use the allocator to automatically manage the memory of the contained elements. Without it, things would be more cumbersome and thus more difficult to use. Furthermore an allocator can be used to perform different techniques of memory management, eg stack allocation, linear allocation, heap allocation, pool allocation etc.

C++ memory "hierarchy"

_________________
|Applications   |
|_______________|
      |
______↓_______________________
|C++ library (std::allocator)|
|____________________________|
      |
______↓______________________________________________________________________________
|C++ primitives (new/delete, new[]/delete[], ::operator new()/::operator delete())  |
|___________________________________________________________________________________|
      |
______↓______
|malloc/free|
|___________|
      |
______↓______________
|OS APIs, syscalls  |
|___________________|

This is the normal flow of calls, but an application can instead call malloc/free, or new/delete or even the OS APIs directly. You see it's ALL an abstraction. The level above abstracts the more difficult nature of the one and wraps it in an easier to use package.

참고URL : https://stackoverflow.com/questions/31358804/whats-the-advantage-of-using-stdallocator-instead-of-new-in-c

반응형