Operator new initialisiert den Speicher auf Null

Es gibt einen solchen Code:

#include  int main(){ unsigned int* wsk2 = new unsigned int(5); std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl; delete wsk2; wsk2 = new unsigned int; std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl; return 0; } 

Ergebnis:

 wsk2: 0x928e008 5 wsk2: 0x928e008 0 

Ich habe gelesen, dass new Speicher nicht mit Nullen initialisiert. Aber hier scheint es so zu sein. Wie funktioniert es?

Solutions Collecting From Web of "Operator new initialisiert den Speicher auf Null"

Es gibt zwei Versionen:

 wsk = new unsigned int; // default initialized (ie nothing happens) wsk = new unsigned int(); // zero initialized (ie set to 0) 

functioniert auch für Arrays:

 wsa = new unsigned int[5]; // default initialized (ie nothing happens) wsa = new unsigned int[5](); // zero initialized (ie all elements set to 0) 

In Antwort auf Kommentar unten.

Ehm … bist du sicher, dass das neue vorzeichenlose int5 die ganzen Zahlen auf Null setzt?

Anscheinend ja:

[C ++ 11: 5.3.4 / 15]: Ein new-Ausdruck, der ein Objekt vom Typ T erzeugt, initialisiert dieses Objekt wie folgt: Wenn der new-initializer weggelassen wird, wird das Objekt standardmäßig initialisiert (8.5); Wenn keine Initialisierung durchgeführt wird, hat das Objekt einen unbestimmten Wert. Andernfalls wird der Neuinitialisierer gemäß den Initialisierungsregeln von 8.5 für die direkte Initialisierung interpretiert.

 #include  #include  int main() { unsigned int wsa[5] = {1,2,3,4,5}; // Use placement new (to use a know piece of memory). // In the way described above. // unsigned int* wsp = new (wsa) unsigned int[5](); std::cout < < wsa[0] << "\n"; // If these are zero then it worked as described. std::cout << wsa[1] << "\n"; // If they contain the numbers 1 - 5 then it failed. std::cout << wsa[2] << "\n"; std::cout << wsa[3] << "\n"; std::cout << wsa[4] << "\n"; } 

Ergebnisse:

 > g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.2.0 Thread model: posix > g++ t.cpp > ./a.out 0 0 0 0 0 > 

operator new wird nicht garantiert, dass Speicher auf irgendwas initialisiert wird, und der new-Ausdruck , der ein unsigned int ohne einen new-initializer zuweist, hinterlässt das Objekt mit einem unbestimmten Wert.

Das Lesen des Werts eines nicht initialisierten Objekts führt zu einem nicht definierten Verhalten . Undefiniertes Verhalten beinhaltet die Bewertung auf den Wert Null ohne negative Auswirkungen, kann aber dazu führen, dass etwas passiert, also sollten Sie es vermeiden.

In C ++ 11 wird als Sprache verwendet, dass die zugeordneten Objekte standardmäßig initialisiert werden, was bei Nicht-classntypen bedeutet, dass keine Initialisierung durchgeführt wird. Dies unterscheidet sich von der Bedeutung von default-initialisiert in C ++ 03.

Bei einigen Compilern wird die Debug-Version von new die Daten initialisieren, aber es gibt sicherlich nichts, auf das Sie sich verlassen können.

Es ist auch möglich, dass der Speicher gerade 0 von einer vorherigen Verwendung hatte. Gehen Sie nicht davon aus, dass dem Speicher zwischen Löschen und Neu nichts passiert ist. Es könnte etwas im Hintergrund geschehen, das du nie bemerkt hast. Derselbe pointerswert ist möglicherweise nicht derselbe physische Speicher. Speicherseiten werden verschoben und ausgelagert. Ein pointers wird möglicherweise an einer anderen Stelle als zuvor zugeordnet.

Fazit: Wenn Sie einen Speicherort nicht gezielt initialisiert haben, können Sie von dessen Inhalt nichts annehmen. Der Speichermanager reserviert möglicherweise nicht einmal einen bestimmten physischen Speicherort, bis Sie den Speicher verwenden.

Modernes Speichermanagement ist erstaunlich komplex, aber als C ++ – Programmierer ist es Ihnen egal (meistens ‡). Spielen Sie nach den Regeln und Sie werden nicht in Schwierigkeiten geraten.

‡ Es ist möglicherweise wichtig, dass Sie optimieren, um Seitenerrors zu reduzieren.

Das ist kein operator new , das ist der new Operator. Es gibt tatsächlich einen großen Unterschied! Der Unterschied besteht darin, dass der operator new eine function ist, die den rohen Speicher zurückgibt. Wenn Sie den new Operator verwenden, ruft er einen Konstruktor für Sie auf. Es ist der Konstruktor, der den Wert dieses int , nicht den operator new .