Beachten Sie, dass die Null-Initialisierung, die vom Betriebssystem als Sicherheitsfunktion durchgeführt wird, normalerweise erst beim ersten Speicherzugriff erfolgt. Damit meine ich jedes Segment in den Heap-, Stack- und Datenabschnitten. Die Stapel- und Datenabschnitte haben typischerweise eine feste Größe und werden initialisiert, wenn die Anwendung in den Speicher geladen wird.
Das Datensegment (mit statischen/globalen Daten und Code) wird normalerweise nicht "wiederverwendet", obwohl dies möglicherweise nicht der Fall ist, wenn Sie den Code zur Laufzeit dynamisch laden.
Der Speicher im Stack-Segment wird immer wieder verwendet. Lokale Variablen, Funktionsstapelrahmen usw. werden ständig verwendet und wiederverwendet und nicht jedes Mal initialisiert - gerade wenn die Anwendung zum ersten Mal geladen wird.
Wenn die Anwendung jedoch Anforderungen für Heap-Speicher stellt, initialisiert der Speichermanager normalerweise Speichersegmente, bevor die Anforderung erteilt wird, jedoch nur für neue Segmente. Wenn Sie eine Anforderung für Heap-Speicher stellen und in einem bereits initialisierten Segment freier Speicherplatz vorhanden ist, wird die Initialisierung nicht ein zweites Mal durchgeführt. Daher gibt es keine Garantie, dass, wenn dieses bestimmte Speichersegment von Ihrer Anwendung wiederverwendet wird, es erneut initialisiert wird.
Wenn Sie zum Beispiel ein Foo auf dem Heap zuweisen, seinem Feld einen Wert zuweisen, die Foo-Instanz löschen und dann ein neues Foo auf dem Heap erstellen, besteht die Möglichkeit, dass das neue Foo zugewiesen wird an der gleichen genauen Speicherstelle wie der alte Foo, und so wird sein Feld anfangs den gleichen Wert wie das alte Foo-Feld haben.
Wenn Sie darüber nachdenken, ist dies sinnvoll, da das Betriebssystem die Daten nur initialisiert, um zu verhindern, dass eine Anwendung auf die Daten von einer anderen Anwendung zugreift. Es besteht ein geringeres Risiko, dass eine Anwendung auf ihre eigenen Daten zugreifen kann. Aus Gründen der Performance wird die Initialisierung nicht jedes Mal durchgeführt, sondern nur dann, wenn ein bestimmtes Speichersegment für die Anwendung (in jedem Segment) verfügbar gemacht wird.
Wenn Sie eine Anwendung im Debug-Modus ausführen, initialisieren einige Debugmodus-Laufzeiten manchmal Stapel- und Heap-Daten bei jeder Zuordnung (so wird Ihr Foo-Feld immer initialisiert). Unterschiedliche Debug-Laufzeiten initialisieren die Daten jedoch auf unterschiedliche Werte. Einige Null initialisiert und einige initialisieren auf einen "Marker" -Wert.
Der Punkt ist - verwenden Sie nie irgendwo in Ihrem Code nicht initialisierte Werte. Es gibt absolut keine Garantie, dass sie null initialisiert werden. Stellen Sie außerdem sicher, dass Sie den zuvor verlinkten Artikel zu parens und der Standard-vs-Wert-Initialisierung lesen, da sich dies auf die Definition eines "nicht initialisierten" Werts auswirkt.
Sind Sie sicher, dass es C++ ist und nicht, sagen wir, Ihr Betriebssystem? Ich könnte mir vorstellen (aber nicht überprüft haben), dass, wenn ein Betriebssystem Speicher zu Ihrem Prozess zuweist, würde es Null, zumindest wenn Sie die Speicherseite berührt. Weder C noch C++ erfordern dieses Verhalten, aber wenn das Betriebssystem die Speicherseiten mit dem letzten Prozess ausgibt, wäre es ein großes Sicherheitsloch. Dort könnten Anmeldeinformationen oder private Schlüssel enthalten sein, wenn ssh zum Beispiel der letzte Prozess war, der diese physische Speicherseite verwendet. –
Es wäre verschwenderisch für das Betriebssystem, den Speicher bei der Zuweisung auf Null zu setzen. – Alan
Sie könnten auch den ausgezeichneten, verwandten Beitrag lesen von Michael Burr in Antwort auf [Machen die Klammern nach dem Typnamen einen Unterschied mit neuen?] (Http://stackoverflow.com/questions/620137/do-the-parentheses- after-the-type-name-make-a-difference-with-new/620402 # 620402) –