최근에 할당 자의 여러 인스턴스간에 공유되는 메모리 풀을 기반으로 사용자 지정 할당자를 개발하는 일이있었습니다. STL 컨테이너, SBO 및 사용자 정의 할당 자 충돌
의도
는 할당이그러나 특히 뭔가 좀 혼란이 발생했습니다 등등 벡터, 양단 큐,지도, 문자열 기반의 컨테이너 ++ STL 및 표준 C와 호환 될 것이 었습니다. std :: vector, std :: string과 같은 컨테이너의 다양한 구현은 작은 버퍼 최적화 - 작은 초기 메모리 요구 사항에 대한 스택 기반 할당을 사용합니다. 예를 들어 MSVC9.1를 들어
는 basic_string 클래스에서 다음 멤버가 있습니다
union _Bxty
{ // storage for small buffer or pointer to larger one
_Elem _Buf[_BUF_SIZE];
_Elem *_Ptr;
char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;
내가 그런 용기를 인스턴스화 할 때 일 만에 구현 을 부추 항상 제공 할당을 사용하는 방법을 볼 수 없습니다를 SBO를 사용하지 마십시오. 사용자 지정 할당자를 구현하려는 의도 중 하나가 공유 메모리의 양을 컨텍스트에서 사용할 수 있기 때문에 묻습니다. 공유 메모리의 양은 SBO 제한 인 미만일 수 있습니다. 다양한 구현 중 일부가 사용할 수 있습니다.
예를 들어 나는 표준의 두 경우 : 일반적인 블록 메모리의 SBO에 어쩌면보다 작거나 같은 상위 제한을 공유하는 프로세스 당 문자열 하나를 가질 수있는 상황을 가지고 싶습니다.
은 아마 관련 : May std::vector make use of small buffer optimization?
typedef std::vector<int,mysharedmemallocator> shmvtype;
shmvtype v(2,0); //<-- if SBO then error as memory is allocated on
//stack not via the allocator
v[1] = 1234; //<-- if SBO then error as wrong piece of memory
// is being modified.
는 이상 어떤 사람들을 위해 일을 복잡하게 보인다 공유 메모리를 기반으로하지 않는 또 다른 예를 살펴 수 있습니다. 내가 std :: basic_string 또는 std :: vector 등을 특수화하고 싶다고 말하면서, 0xMB로 할당 한 메모리를 채우는 할당자를 가지고, 기발한 것 외의 이유없이 호출하는 엔티티에 포인터를 다시 보내기 전에 말이다.
이 새 할당 자에 특수화되어 있지만 SBO를 사용하는 컨테이너는 0xAB 패턴으로 채워진 SBO 기반 메모리를 가지지 않습니다. 그래서 예를 들면 : 사용자 정의 할당자를 구현하는 의도
typedef std::basic_string<char,myfillmemallocator> stype
stype s;
s.resize(2);
assert(s[0] == 0xAB); // if SBO this will fail.
Nicol,하지만 단 한 가지 질문에 대해 공유 메모리를 할당하는 할당자를 가질 수 없으며 오프셋 포인터 개념을 통해 메모리의 별명을 지정할 수 없습니다. 이것은 정상적으로 수행되는 방식입니다 (boost.interprocess). 확실히 할 수없는 이유를 이해합니다. –
@ 세미나 : 그 문자열을 복사하면 어떻게됩니까? 해당 문자열에 문자를 삽입하면 재 할당이 발생할 수 있습니다. 이러한 작업의 의미가 무엇인지 분명하지 않지만 한 가지 분명한 사실은 의미가 무엇이든 구현 자체가 알아야하는 의미입니다. 즉, 일을 특정 방식으로 수행하는 특정 컨테이너 구현이 필요합니다. –
공유 문자열에서 다른 문자열로 복사하는 것은 일반적인 복사입니다. 대상 문자열은 공유 메모리를 가질 것으로 예상되지 않습니다. 이것은 다른 방법으로도 동일합니다. 표준 std :: string에서 공유 문자열 데이터로 복사됩니다. 특수화 된 할당 자에 의해 제공되는 공유 메모리에 저장하십시오 .- 따라서 이것은 크기 변경/추가 등과 관련된 질문 –