2012-04-11 11 views
0

Im mit der "* glibc erkannt /home/ubuntu [....]: double frei oder Korruption (fasttop): 0x09851168 * *" -Problem.C++ Speicherfehler ("double freie oder Korruption")

Debuggen dachte ich die Zeile aus, die die Quelle des Problems zu sein scheint:

data[i]->~Class(); 

wich bezieht sich auf

class Class { 
public: 
    Class(); 
    Class(char *name, double value); 
    virtual ~Class(); 
    char *name; 
    double value; 
private: 

}; 

dann

Class::Class() { 
} 

Class::Class(char* name, double value){ 
    this->name = new char[std::strlen(name)]; 
    std::strcpy(this->name, name); 
    this->value = value; 
} 

Class::~Class() { 
    delete name; 
} 

jetzt I‘, offensichtlich Ich mache da was falsch. Kann mir jemand was sagen?

+0

Für diese Art von Fehler lohnt es sich normalerweise, unter valgrind zu laufen, um mehr Informationen darüber zu bekommen, was das Problem verursacht.(Aber ich vermute, dass die bereits geposteten Antworten korrekt sind) –

Antwort

1

Ich kenne nur ein paar Umstände, unter denen Sie verwenden: data[i]->~Class();. Zum einen verwenden Sie Placement neu, um ein Objekt an diesem Ort zu erstellen. Die andere besteht darin, dass Sie ein Objekt neu initialisieren, indem Sie es zerstören, und sofort gefolgt von der Verwendung von placement new, um dort ein neues Objekt zu erstellen. Beide sind ziemlich fortgeschrittenen Techniken, und ganz ehrlich gesagt, eher ungewöhnlich, außer wenn Sie erstellen eine eigene Sammlung Klasse.

Meine Vermutung ist, dass 1) du das nicht brauchst, und 2) du hast uns nicht wirklich den Code gezeigt, der wichtig ist (was wahrscheinlich der Inhalt ist, der den expliziten dtor-Aufruf umgibt).

Sie haben Sie eine andere kleinere Problem bei Aufteilung name mit new[], und es mit delete name; Löschen - die beiden zusammenpassen sollten, so dass Sie delete [] name; verwenden sollten. Angesichts der Tatsache, dass es sich um ein Array von char handelt, handelt es sich jedoch hauptsächlich um eine technische Eigenschaft, die in diesem Fall höchstwahrscheinlich kein Problem verursachen wird. Wenn es sich um ein Array von Objekten mit nicht-trivialen Destruktoren handelt, wäre das typische Symptom, dass einige (die meisten) Objekte nicht ordnungsgemäß zerstört wurden (d. H. Ihre Destruktoren würden nicht aufgerufen). In der Theorie ist es nur undefiniertes Verhalten, also kann alles geschehen, aber die wirklichen Chancen davon, die Quelle Ihres Problems zu sein, sind extrem entfernt (besonders, wie ich sagte, im Falle eines Arrays von char).

Natürlich, was Sie wirklich tun sollten, ist name ein std::string machen und den ganzen Unsinn völlig überspringen.

+0

"Das andere ist, dass Sie ein Objekt neu initialisieren, indem Sie es zerstören, um sofort gefolgt zu werden, indem Sie Placement neu verwenden, um dort ein neues Objekt zu erstellen." Das ist der Fall. Es ist eine Liste von Objekten, also rufe ich den Destruktor auf, wenn ich ein Objekt "Class" aus der Liste entferne. –

+0

@Johnsmith: In diesem Fall würde es sich wahrscheinlich lohnen, diesen Code zu posten, damit wir sehen können, wie er funktioniert (oder nicht funktioniert, je nachdem). –

7

Das, was Sie falsch explizit tut bist Aufruf einer destructor:

data[i]->~Class(); 

Es sei denn, Sie absolut wissen, dass Sie explizit aufrufen sollte (dies ist ungewöhnlich, und viele große Programme nie eine Notwendigkeit zu tun), dann sollten Sie wahrscheinlich delete verwenden statt:

delete data[i]; 
1
data[i]->~Class(); 

Sie sollten nie eine destruct nennen oder so. Entweder delete, wenn es mit new zugewiesen wurde, oder einfach nichts tun und der Destruktor wird aufgerufen, wenn das Objekt den Gültigkeitsbereich verlässt.