[SOLVED] virtual ~Base()+virtual Derived::operator=()==crash

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

[SOLVED] virtual ~Base()+virtual Derived::operator=()==crash

Beitrag von kaiserludi »

Code: Alles auswählen

class B
{
public:
	virtual ~B(){};
	// alternativ führt
	// virtual void foo();
	// ~B();
	// zum gleichen Ergebnis
};

class A : public B
{
public:
	virtual A& operator=(const A& toCopy)
	{
		return *this;
	}
};

Code: Alles auswählen

int main(void)
{
	A* a = (A*)malloc(2*sizeof(A));
	new(a+0) A;
	new(a+1) A;
	a[0].~A();
	a[0] = a[1]; // crash
	a[1].~A();
	free(a);
}
Ich stehe gerade auf dem Schlauch, wieso MSVC2010 mir hier um die Ohren fliegt, sobald B mindestens eine virtuelle Funktion UND einen explizit deklarierten Destruktor UND zusätzlich A einen virtuellen Zuweisungsoperator für A& hat. Wenn der Zuweisungsoperator von A eine B& nimmt, gibts kein Problem (natürlich nur solange es nicht zusätzlich noch einen zweiten gibt, der eine A& nimmt, weil der sonst aufgerufen werden würde). Das Problem tritt auch nicht auf, wenn der Zuweisungsoperator von A nicht virtuell ist ().

Könnt ihr mir auf die Sprünge helfen, warum diese Kombi ein Problem ist?
Zuletzt geändert von kaiserludi am 07.02.2013, 22:52, insgesamt 1-mal geändert.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: virtual ~Base() + virtual Derived::operator=() == crash?

Beitrag von CodingCat »

Code: Alles auswählen

a[0].~A(); // a[0] wird ZERSTÖRT
a[0] = a[1]; // Falsch: a[0] kein gültiges Objekt mehr, darf nicht länger wie gültiges Objekt modifiziert werden
kaiserludi hat geschrieben:Ich stehe gerade auf dem Schlauch, wieso MSVC2010 mir hier um die Ohren fliegt, sobald [...] A einen virtuellen Zuweisungsoperator für A& hat.
Weil dein a[0]-Objekt vor der Zuweisung zerstört wurde und somit insbesondere keinen passenden V-Table-Zeiger mehr hat.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: virtual ~Base() + virtual Derived::operator=() == crash?

Beitrag von kaiserludi »

Das heißt, dass die Zuweisung nach der Dekonstruktion durchgeht, wenn entweder der Zuweisungsoperator von A oder nichts von B virtuell ist oder B nur einen kompilererzeugten Destruktor hat, ist einfach Glück, aber wohldefiniertes Verhalten ist es dann eigentlich genauso wenig, korrekt?
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: virtual ~Base() + virtual Derived::operator=() == crash?

Beitrag von CodingCat »

Genau, sobald dein Objekt zerstört wurde, ist solange keine Objektoperation darauf wohldefiniert, bis du an derselben Stelle wieder ein neues Objekt konstruiert hast.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: virtual ~Base() + virtual Derived::operator=() == crash?

Beitrag von kaiserludi »

So wird ein Schuh draus. Eigentlich auch klar. Dass in den meisten Fällen das undefinerte Verhalten einfach kein Problem verursacht hat, hat mich da wohl blind dafür gemacht, dass die Zuweisung ohne vorherige neue Konstruktion an der Stelle dennoch ein Bug ist. Danke.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [SOLVED] virtual ~Base()+virtual Derived::operator=()==c

Beitrag von Krishty »

Nunja; außer für POD. Dann beginnt mit der Zuweisung automatisch die neue Lebenszeit und alles ist wohldefiniert. Hat GCCs Aliasing-Analyse viele Kopfschmerzen bereitet.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten