2016-08-04 22 views
-1

Ich bin Ware, dass die Methode std :: vector.reserve() die Kapazität eines Vektors reserviert und den Zugriff auf einen Vektor, der reserviert, aber nicht manuell mit Werten initialisiert wird, zu einem undefinierten Verhalten führen. Aber mir wurde gesagt, dass die reserve() Methode tatsächlich etwas in den zugewiesenen Speicher füllt, also kann es nicht eine nicht initialisierte Speicherzuweisung sein, richtig? Gibt es also jemals eine Möglichkeit, nicht initialisierten Speicher in C++ zuzuweisen (wie funktioniert mcalloc() für c)?nicht initialisierte Speicherzuweisung in C++

EDIT: Entschuldigung, ich habe das falsche Wort hier, es sollte wie mcalloc() funktioniert für c. Ich habe das geändert.

+0

'wie calloc() funktioniert für c .. .. scherzen oder ernst? Das ist wie 180 Grad gegenüberliegende Aussage. –

+0

'Calloc' weist initialisierten Speicher zu. Es gibt eine Möglichkeit, nicht initialisierten Speicher in C++ zuzuweisen, so wie 'malloc' für C funktioniert: Es wird' malloc' verwendet. Es gibt auch eine Möglichkeit, Speicher in C++ zuzuordnen, so wie 'calloc' für C funktioniert: es ist' calloc' zu verwenden. – wasthishelpful

+0

Die Antworten sind ein wenig divergierend - könntest du bitte klarstellen, ob 'std :: vector' die Crux deiner ist Frage oder nur ein Beispiel? Möchten Sie ein nicht initialisiertes Objekt in einen Vektor einfügen oder einfach nur nicht initialisierten Speicher zuweisen? – Quentin

Antwort

2

Das undefinierte Verhalten resultiert aus der Verletzung des Vertrags der std::vector Schnittstelle.

Ja, Speicher ist zugewiesen, daher erhalten Sie keine Speicherzugriffsverletzung.

Nein, es ist nicht initialisiert. Es ist wahrscheinlich erstellt mit new char[N] oder Somesuch, so ist es nur ein Haufen von nicht initialisierten char s bietet einen "Spielplatz", auf dem der Vektor später Zeug bauen kann.

Für einen integralen Elementtyp ist das kein Problem (es sei denn, Sie werden die unbestimmten Werte lesen). Für Klassen-Typen ist das ein Problem, da ihre Konstruktoren nicht ausgeführt wurden und daher die Objekte "nicht existieren".

Können Sie es hacken, indem Sie manuell Objekte an diesem Ort erstellen? Vielleicht mit neuer Platzierung? Sicher. Genau das tut der Vektor! Aber du würdest immer noch die Schnittstelle von std::vector verletzen, dein Programm mit Undefined Behavior und so — aus einer Black-Box-Perspektive — müssen Sie akzeptieren, dass alles passieren kann, egal wie gut Sie denken, dass Sie es unter der Haube hacken.

Stattdessen können Sie ein solches Objekt ordnungsgemäß erstellen, indem Sie es einfach über seine dokumentierte Schnittstelle zum Vektor hinzufügen. Also tu das einfach.

1

Wenn Sie den neuen Operator verwenden, wird der Speicher nicht initialisiert, wenn Sie einen Integer-Datentyp verwenden. Wie char* my_mem = new char[N]. Dieser Speicher wird nicht initialisiert und kann einen beliebigen Wert enthalten. Wenn Sie jedoch etwas wie std::string my_words = new std::string[N] haben. Thesen würden alle auf leere Strings initialisiert werden, da es sich um eine Klasse und neu um den Standardkonstruktor handelt. Davon abgesehen würde ich mir vorstellen, dass die Reservefunktion diesem Verhalten folgt. Wenn es eine Klasse reserviert, würde es den Standardkonstruktor aufrufen, und wenn es ein Integertyp ist, würde es dies nicht tun.

+0

Ich hoffe, dass 'reserve'() in diesem Kontext keine Ctors aufruft. Das wäre teuer, wenn die Kosten hoch sind. (Es kann ihre Anwesenheit zur Kompilierungszeit erfordern, iiuc jedoch.) –