Seite 1 von 1
[SOLVED] virtual ~Base()+virtual Derived::operator=()==crash
Verfasst: 07.02.2013, 21:34
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?
Re: virtual ~Base() + virtual Derived::operator=() == crash?
Verfasst: 07.02.2013, 21:42
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.
Re: virtual ~Base() + virtual Derived::operator=() == crash?
Verfasst: 07.02.2013, 22:35
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?
Re: virtual ~Base() + virtual Derived::operator=() == crash?
Verfasst: 07.02.2013, 22:40
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.
Re: virtual ~Base() + virtual Derived::operator=() == crash?
Verfasst: 07.02.2013, 22:51
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.
Re: [SOLVED] virtual ~Base()+virtual Derived::operator=()==c
Verfasst: 08.02.2013, 11:47
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.