2017-12-12 1 views
0

Wenn Allocator entspricht der Standard-Bibliothek Allokator-Schnittstelle, ist es sicher, std::allocator_traits<Allocator>::deallocate mit einem Nullzeiger aufzurufen? Ich weiß, es ist, wenn Allocator ist std::allocator (weil es schließlich auf delete deferiert) aber was ist, wenn Allocator ist eine Client-Klasse zur Verfügung gestellt? Muss ich eine explizite Überprüfung durchführen? cppreference.com 's Artikel über die Allocator concept listet keine solche Garantien, so denke ich, die Antwort ist "Ja", aber ich wollte sicher sein.Aufruf von allocator_traits :: Zuweisung auf einen Null-Zeiger

Um ein wenig Motivation für die Frage zu geben, stelle ich mir einen Anwendungsfall vor, wo eine Variable einen Zeiger auf den Puffer halten soll (und anfangs auf nullptr gesetzt ist), aber aus irgendeinem Grund war der Puffer nie an erster Stelle zugewiesen, so bleibt ein Nullzeiger.

+0

Sie meinen, dass Zeiger auf Speicher ist nullptr UND Anzahl der Objekte ist> 0? –

+0

Ändert sich die Antwort abhängig davon, ob die Anzahl der Objekte Null ist oder nicht? –

+0

Mein Eindruck ist gewesen, dass, wenn der zugeordnete Allokator nullptr zu allocate zurückgeben kann, nullptr auch ein gültiges Argument ist, um die Zuordnung aufzuheben. Ich kann mir jedoch nicht vorstellen, warum es nullptr zurückgibt, wenn die Anzahl der Objekte> 0 ist. –

Antwort

2

Zunächst einmal std::allocator<T>::deallocate(T* p, std::size_t) tut nicht Anruf delete p. Stattdessen ruft sie operator delete(p) gemäß 23.10.9.1 [allocator.members] Absatz 7 auf. Stattdessen besagt die Anforderung in Absatz 5 desselben Absatzes, dass von std::allocator<T>::allocate() erhalten werden muss. Diese Funktion kann keinen Nullzeiger zurückgeben, d. H. std::allocator<T>::deallocate() akzeptiert keine Nullpunkte. Es wäre überraschend, wenn das Allokator-Konzept erlaubt, Nullzeiger zu übergeben, da std::allocator<T> dieses Konzept nicht modellieren würde. Das Zuweiserkonzept in Tabelle 31 erfordert ebenfalls, dass das Argument a.deallocate(p) von a.allocate() erhalten wurde. Da die Spezifikation a.allocate(n) immer genügend Speicher für n Objekte zurückgibt (die einzige Fehleranzeige erfolgt über eine Ausnahme), folgt daraus, dass a.deallocate() nicht mit einem Nullzeiger zu rechnen ist.

Die Frage war etwa allocator_traits<...>::deallocate(). Gemäß 23.10.8.2 [allocator.traits.members] Absatz 3 delegiert diese Funktion lediglich an die Funktion deallocate() des Allokators. Das heißt, ein Nullzeiger ist auch dort kein gültiges Argument.

+0

Wenn die Anzahl der angegebenen Objekte 0 ist, dann ist das, was Allocator :: allocate zurückgibt, unspezifiziert. "Nicht angegeben" bedeutet einen gültigen Wert, der der Implementierung (oder dem benutzerdefinierten Zuordner) zur Angabe überlassen wird. Kann es nicht nullptr sein? –

+0

@ ÖöTiib: eine Implementierung eines Zuweisers kann wählen, "Nullptr" als seine Darstellung für eine Null-Sequenz von Objekten zu verwenden. Es ist jedoch nicht garantiert, dass dies der Fall ist, d.h. Benutzer können keine Annahme machen, dass "nullptr" eine gültige Darstellung ist. –

Verwandte Themen