Ich habe kürzlich an der Entwicklung eines benutzerdefinierten Zuordners gearbeitet, der auf einem Speicherpool basiert, der von mehreren Instanzen des Zuweisers gemeinsam genutzt wird.Konflikte bei STL-Containern, SBO und benutzerdefinierten Zuordnern
Die Absicht war, dass der Verteiler mit STL und Standard C++ basierte Container wie Vektor, deque, Karte, string etc
jedoch etwas Bestimmtes verursacht hat mir einige Verwirrung kompatibel sein. Verschiedene Implementierungen der Container wie Std :: Vector, Std :: String nutzen Small Buffer Optimization - Stack-basierte Zuordnung für kleine anfängliche Speicheranforderungen.
Zum Beispiel MSVC9.1 hat das folgende Element in der basic_string Klasse:
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;
ich nicht sehen kann, wie wenn solche Behälter Instanziieren einer die Implementierung nur und immer verwenden Sie den mitgelieferten allocator schmeicheln kann und nicht SBO verwenden. Ich frage, weil einer der Absichten der Implementierung benutzerdefinierte Zuweisungen war in der Lage, sie in einem gemeinsamen Speicher Kontext zu verwenden, wo die Menge des gemeinsamen Speichers weniger als der SBO-Grenze einige der verschiedenen Implementierungen verwenden können.
Zum Beispiel würde Ich mag eine Situation haben, wo ich zwei Instanzen von std haben :: string eine pro Prozess einen gemeinsamen Block Speicher teilen, die vielleicht kleiner als oder gleich dem SBO oberen Grenze.
Möglicherweise verwandte: 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.
Lässt ein anderes Beispiel, die auf gemeinsam genutzten Speicher nicht basiert, wie es Dinge für einige Menschen über zu erschweren scheint. Nehmen wir an, ich möchte meinen std :: basic_string oder std :: vector usw. mit einem Zuordner spezialisieren, der den Speicher füllt, den er mit dem Wert 0xAB reserviert, bevor er den Zeiger zurück zu der aufrufenden Einheit für keinen anderen Grund als launisch präsentiert.
Ein Container, der auf diesen neuen Zuordner spezialisiert ist, aber auch SBO verwendet, wird seinen SBO-basierten Speicher nicht mit 0xAB-Muster gefüllt haben. So zum Beispiel:
typedef std::basic_string<char,myfillmemallocator> stype
stype s;
s.resize(2);
assert(s[0] == 0xAB); // if SBO this will fail.
Danke für den Kommentar Nicol, aber nur eine Frage, kann man nicht einen Zuordner haben, der Shared Memory zuweist, und Aliase den Speicher über ein Offset-Zeiger-Konzept - So wird es normal gemacht (boost.interprocess), nicht Sicher verstehe ich, warum es nicht getan werden kann. –
@Seminar: Und was passiert, wenn Sie diese Zeichenfolge kopieren? Was passiert, wenn Sie ein Zeichen in diese Zeichenfolge einfügen und dadurch eine Neuzuweisung verursachen? Es ist nicht klar, was die Semantik einer dieser Operationen sein sollte, aber eines ist klar: Was auch immer die Semantik ist, sie sind Semantiken, über die die Implementierung selbst Bescheid wissen muss. Das heißt, Sie benötigen eine bestimmte Containerimplementierung, die die Dinge auf eine bestimmte Art und Weise erledigt. –
In Bezug auf Kopieren von der gemeinsamen Zeichenfolge in eine andere Zeichenfolge ist eine gemeinsame Kopie, die Zielzeichenfolge wird nicht erwartet, gemeinsam genutzten Speicher zu haben, dies ist auch das gleiche umgekehrt, Kopieren von normalen Std :: String zu Shared String Daten wird kopiert in den geteilten Speicher, der vom spezialisierten Zuordner bereitgestellt wird - Das ist also für die Frage –