C++ auto_ptr in MS VS6.0

Hi,

ich hab ein großes Problem. Ich verwende MS Visual C++ in der Version 6.0. Nun habe ich etwas mit auto_ptr (include memory) herumexperimentiert, aber keine richtigen Ergebnisse erziehlt.
Kann es sein, dass es hier Probleme gibt?

VC kennt z.B. die reset Methode eines auto_ptr nicht. Auch das assign funktioniert nicht wie es soll.

Kann jemand da etwas zu sagen?

Gruß Karsten

Hinweis: nach einer Zuweisung
#include

int main()
{
std::auto_ptr ptr1(new int(4));
std::auto_ptr ptr2;

ptr2 = ptr1;

cout

Hi Karsten :smile:

Die Ausgabe, die du erhälst, ist genau die, die ich erwartet habe. Es scheint mir so, als würde VC alles richtig machen. Im einzelnen:

std::auto_ptr ptr1(new int(4));

Du erzeugst ein int auf dem Heap und initialisierst es mit 4. Die Adresse dieses int wird dem auto_ptr ptr1 zugewiesen.

std::auto_ptr ptr2;

Du erzeugst einen zweiten auto_ptr namens ptr2 ohne ihn zu initialisieren.

ptr2 = ptr1;

Du weist ptr2 den Wert von ptr1 zu. Der Wert von ptr1 ist jedoch ein Zeiger auf den Heap, wo das int-Objekt mit dem Wert 4 steht.

cout

int a=4;
int b;
b= a;

auch erwarten dass nach der Zuweisung b= a, der Wert von a wieder Null ist? Das wäre sicherlich eine Katastrophe :smile:

bei mir:
ptr1 address is 00124456
ptr2 address is 00124456
ptr1 has value 4
ptr2 has value 4

Völlig richtig! So muss es auch sein :smile:

Viele Grüße

Stefan.

Hi Stefan,

wenn ich die STL richtig verstehe, ist der Pointer so implementiert, das „niemals“ zwei auto_ptr auf den gleichen Speicher zeigen dürfen. Sonst könnte der eine auto_ptr der aus seinem Gültigkeitsbereich kommt den Speicher bereits löschen, während mit dem anderen Pointer noch gearbeitet wird.
Außerdem sagt Nicolai M. Josuttis mir das in seinem Buch „The C++ Standard Library“

PS: Und GNU Linux sagt auch, dass es funktioniert wie hier gepostet. Ich hab’s am Wochenende zu Hause probiert.

Ich denke VC hat eine falsche implementierung.

Gruß Karsten

Hi Karsten :smile:

wenn ich die STL richtig verstehe, ist der Pointer so
implementiert, das „niemals“ zwei auto_ptr auf den gleichen
Speicher zeigen dürfen. Sonst könnte der eine auto_ptr der aus
seinem Gültigkeitsbereich kommt den Speicher bereits löschen,
während mit dem anderen Pointer noch gearbeitet wird.

Stimmt, der Standard spricht da von einem „transfer of ownership“. In dem Moment, wo du ptr2=ptr1 schreibst, verliert ptr1 seine Macht über die Adresse und gibt sie an ptr2 ab. Nun sollte ptr1 nicht weiter benutzt werden. Daher wird er auf NULL gesetzt. Das ist das Verhalten, das der Standard vorschreibt. Aber es ist doch nicht das Verhalten, das du wirklich erwartest, oder? Es ist ein völliger Bruch mit dem Zuweisungsoperator in C++, wie ich schon in meinem vorigen Posting geschrieben habe.

Ich denke VC hat eine falsche implementierung.

Wenn du den puren Ansi-C+±Standard zu Grunde legst, dann ja. Wenn du aber die Denkweise eines Programmierers zu Grunde legst, dann hat Microsoft den auto_ptr nur extrem sinnvoll erweitert.

Microsoft führt nämlich einen Referenzzähler ein. Wenn du dann z.B. eine Anweisung wie ptr2=ptr1 schreibst, dann wird der Referenzzähler inkrementiert. Wenn nun ptr1 oder ptr2 zerstört werden (Destruktor), dann wird zunächst der Referenzzähler dekrementiert. Nur wenn dieser gleich 0 ist, wird auch der Speicherbereich, der hinter dem Pointer steckt gelöscht. Mit anderen Worten, ptr1 ist durch die Zuweisung nicht unbrauchbar geworden, sondern kann weiterhin benutzt werden. Daher muss er auch nicht mit dem Wert NULL belegt werden. Und genau das ist doch das Verhalten, das wir als Programmierer erwarten, oder?

Da du ptr1 nach dem Ansi-C+±Standard sowieso nicht mehr verwenden solltest, werden also alle Ansi-C++ konformen Sourcen mit dem Visual-C++ übersetzt. Wie üblich bietet Microsoft dem Programmierer ein wenig mehr, wodurch er allerdings Gefahr läuft, dass seine Programme nur noch mit Visual-C++ übersetzt werden können …

Viele Grüße

Stefan.

1 Like

Alles klar,

das leuchtet mir ein :wink:
Die Lösung ist ok. Leider habe ich nicht damit gerechnte, das Microsoft eine derartige erweiterung eingebaut hat. Woher kommen diese Infos?
Ich bin nun mal von Haus aus ein Linuxianer und wittere deshalb bei allem was aus dem Hause MS kommt erst mal einen Fehler.

Danke nochmal für die Hilfe
Karsten

Hi Karsten :smile:

das leuchtet mir ein :wink:
Die Lösung ist ok. Leider habe ich nicht damit gerechnte, das
Microsoft eine derartige erweiterung eingebaut hat. Woher
kommen diese Infos?

Wir verwenden hier auto_ptr, wann immer es möglich ist. Uns ist auch aufgefallen, dass sich MS auto_ptr anders verhält als es die STL vorsieht. Daher haben wir uns den Source mal intensiv angeschaut und die Sache mit der Referenzzählung entdeckt :smile:

Ich bin nun mal von Haus aus ein Linuxianer und wittere
deshalb bei allem was aus dem Hause MS kommt erst mal einen
Fehler.

Ich habe früher auch viel unter Solaris (Sun ultra) und Unix (Cray-T3E) programmiert (gcc). Wenn du dich mal auf PCs einlässt, dann führt an Microsoft kaum ein Weg vorbei. Mittlerweile möchte ich den Visual-C+±Compiler nicht mehr missen. Alles, was man unter Unix von Hand machen muss, passiert hier automatisch. Leider sind eben da diese seltsamen Erweiterungen von Microsoft. Man gewöhnt sich im Laufe der Zeit daran …

Danke nochmal für die Hilfe

Jederzeit wieder :smile:

Viele Grüße

Stefan.