C ++: Mitgliedszeiger initialisiert?

8

Codebeispiel sollte Dinge erklären:

%Vor%

Offensichtlich sollte pB explizit auf NULL initialisiert werden, um sicher (und klar) zu sein, aber wie es steht, Was ist der Wert von pB nach der Konstruktion von A? Ist es standardmäßig initialisiert (was ist Null?) oder nicht (dh unbestimmt und was auch immer in Erinnerung war). Ich weiß, dass die Initialisierung in C ++ ein paar Regeln hat.

Ich denke, es ist nicht standardmäßig initialisiert; im Debug-Modus in Visual Studio ausgeführt, hat es pB auf 0xcdcdcdcd zeigen - was bedeutet, dass der Speicher wurde neu (auf dem Heap), aber nicht initialisiert. Im Ausgabemodus jedoch zeigt pB immer auf NULL. Ist das nur zufällig und daher nicht verlässlich; oder initiieren diese Compiler es für mich (auch wenn es nicht im Standard ist)? Es scheint auch NULL zu sein, wenn es mit Suns Compiler auf Solaris kompiliert wird.

Ich suche wirklich nach einem bestimmten Verweis auf den Standard, um das eine oder andere zu sagen.

Danke.

    
Daniel 17.07.2009, 16:11
quelle

7 Antworten

11

Hier ist die relevante Passage aus dem Standard:

  

12.6.2 Initialisierung von Basen und Mitgliedern [class.base.init]

     

4 Wenn ein bestimmtes nicht statisches Datenelement oder   Die Basisklasse wird nicht von einem Speicher benannt   Initialisierungs-ID in der   mem-initializer-Liste, dann

     

- Wenn die Entität eine nicht statische Daten ist   Mitglied von (möglicherweise cv-qualifiziert)       Klassentyp (oder Array davon) oder eine Basisklasse und die Entitätsklasse       Ist eine Nicht-POD-Klasse, wird die Entität standardmäßig initialisiert ( dcl.init ).       Wenn die Entität ein nicht statisches Datenelement eines Const-qualifizierten Typs ist,       Die Entitätsklasse muss einen vom Benutzer deklarierten Standardkonstruktor haben.

     

- Andernfalls ist die Entität nicht   initialisiert . Wenn die Entität von       Const-qualifizierter Typ oder Referenztyp oder eines (möglicherweise cv-quali-       fied) POD-Klassenart (oder Array davon), die (direkt oder       indirekt) ein Mitglied eines const-qualifizierten Typs, das Programm ist   krank-       gebildet.

     

Nach dem Aufruf eines Konstruktors für   Klasse X wurde abgeschlossen, wenn ein Mitglied

     

von X ist in der   mem-initializers des Konstruktors, noch
  Standard initialisiert oder initialisiert   während der Ausführung des Körpers von
  der Konstruktor, das Mitglied hat   unbestimmter Wert.

    
Greg Rogers 17.07.2009, 16:35
quelle
4

Laut C ++ 0x Standard Abschnitt 12.6.2.4, im Fall Ihrer Zeigervariable, wenn Sie es nicht in die Initialisierungsliste aufnehmen und Sie es nicht im Körper des Konstruktors setzen, dann hat es einen unbestimmten Wert. 0xCDCDCDCD und 0 sind zwei mögliche solche Werte, wie auch alles andere. : -)

    
Michael Kristofik 17.07.2009 16:40
quelle
1

Ich glaube, das ist ein Artefakt aus den guten alten C-Tagen, in denen man nicht erwarten konnte, was der allokierte Speicher enthält. Als die Standards nach C ++ weiterentwickelt wurden, wurde diese "Konvention" beibehalten. Als die C ++ - Compiler entwickelt wurden, nahmen die einzelnen Autoren es auf sich, dieses Problem zu "beheben". Daher kann Ihre Laufleistung abhängig von Ihrem gewählten Compiler variieren.

Das "0xcdcdcdcd" scheint ein leicht erkennbares Muster zu sein, das beim Debuggen von Code "hilft". Deshalb wird es im Freigabemodus nicht angezeigt.

Ich hoffe, das hat ein bisschen geholfen und viel Glück.

    
Craig 17.07.2009 16:22
quelle
0

Der Wert von pB ist nicht definiert. Es kann oder kann nicht konsistent der gleiche Wert sein - hängt normalerweise davon ab, was vorher an der gleichen Stelle im Speicher vor der Zuweisung einer bestimmten Instanz von A war.

    
sean e 17.07.2009 16:26
quelle
0

Nicht initialisierte Zeiger können auf alles zeigen. Einige Compiler-Anbieter helfen Ihnen dabei und zeigen auf 0 oder 0xcdcdcdcd oder was auch immer.

Um sicherzustellen, dass Ihr Code sicher und portabel ist, sollten Sie Ihre Zeiger immer initialisieren. entweder auf 0 oder auf einen gültigen Wert.

z.B.

%Vor%

oder

%Vor%

Wenn Sie Zeiger immer auf 0 initialisieren, ist dies sicher:

%Vor%

Wenn Sie sich nicht initialisieren, haben Sie keine Möglichkeit, initialisierte und nicht initialisierte Zeiger voneinander zu unterscheiden.

Abgesehen davon gibt es in C ++ kein solches Schlüsselwort als NULL. Die meisten Compiler definieren NULL als 0, aber sie werden nicht als portabel betrachtet. Der neue c ++ 0x-Standard wird ein neues Schlüsselwort, nullptr, einführen. Wenn das herauskommt, haben wir endlich eine portable Null-Zeiger-Konstante.

    
Glen 17.07.2009 16:26
quelle
0

Es ist selten, dass ich Ihnen rate, nichts über die Sprache zu lernen, die Sie verwenden, aber in diesem Fall ist es nicht nützlich, ob pB initialisiert wird oder nicht. Initialisiere es einfach. Wenn es automatisch initialisiert wird, optimiert der Compiler die zusätzliche Initialisierung. Wenn dies nicht der Fall ist, haben Sie eine zusätzliche Prozessoranweisung hinzugefügt und eine ganze Reihe potentieller Fehler verhindert.

    
Imagist 17.07.2009 17:20
quelle
0

Nicht initialisierte Zeiger können grundsätzlich einen zufälligen Wert enthalten, obwohl manche Compiler dazu neigen, sie mit 0 oder einem anderen erkennbaren Wert zu füllen, besonders im Debug-Modus.

IMHO ist dies wegen C ++ 's "nicht für das, was Sie nicht verwenden" -Design bezahlen. Wenn Sie es nicht für wichtig halten, muss der Compiler nicht die Kosten der Initialisierung der Variablen für Sie übernehmen. Natürlich, sobald Sie einen zufälligen Zeiger verfolgt haben, finden Sie es vielleicht ratsam, es beim nächsten Mal zu initialisieren ...

    
Timo Geusch 17.07.2009 16:37
quelle

Tags und Links