warum ist eine Skalare löschen der Destruktor aufgerufen wird, als Ergebnis der Vektor löschen auf Windows?
Ich habe einen code, der undicht ist auf Windows. Es gut läuft auf vielen unix-Plattformen und das Leck tritt nur auf Windows.
Den binären besteht aus exe -, 1 dll und 2 statische libs. Die exe links, um die dll und die statische libs, während die statischen libs link mit der dll. Der Speicherverlust tritt auf, in den exe-code, wenn statt einer vector deleting destructor, aus irgendeinem Grund scalar deleting destructor aufgerufen wird. Dies führt nur das erste Objekt im array gelöscht werden, während der rest des Arrays im Arbeitsspeicher verbleibt.
Undicht pseudo-code sieht wie folgt aus:
class MyClassFromExe : public MyBaseClassFromDll {
public:
ClassFromDll* m_arr;
MyClassFromExe(unsigned int size)
{
m_arr = new ClassFromDll[size];
}
~MyClassFromExe()
{
delete [] m_arr;
}
};
void func()
{
MyClassFromExe obj(3);
}
Wenn func() beendet und der Destruktor aufgerufen wird sehe ich nur den Destruktor des ersten Objekts in m_arr genannt wird. Von debugger sehe ich, dass dies von scalar deleting destructor und nicht von vector deleting destructor. Dies erklärt, warum nur das erste Objekt zerstört wird.
Was brauche ich, um zu verstehen, warum scalar deleting destructor wird aufgerufen, wenn delete [] verwendet???
Fand ich diesen thread - Warum ist vector deleting destructor aufgerufen wird, als Ergebnis einer skalaren löschen?. Ich folgte die Vorschläge dort und sorgte dafür, dass alle Module kompilieren mit /MD /MD.
Wichtig zu bemerken, dass, wenn die dll enthält ClassFromDll war, eine statische Bibliothek und nicht eine dll, alles hat gut funktioniert. Das Leck nur gestartet, wenn die statische Bibliothek wurde geändert, um eine dll.
Während das Programm Lecks im Release-Modus kracht es im Debug-Modus on delete [] m_arr. Der Absturz tritt in dbgdel.cpp Linie 52 - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse).
Auf unix-Plattformen diese lib ist auch eine shared lib und, wie erwartet, vector deleting destructor aufgerufen und es gibt kein Leck. Könnte das problem mit dem VC-compiler? Oder vielleicht einige andere Einstellungen der Projekte geändert werden müssen?
Ich bin mit VC2003.
Vielen Dank im Voraus!
std::vector
Wenn Sie GELTEND machen, die im debug-Modus, wenn Sie versuchen zu tun, um "RETRY" nach dem anfügen des Debuggers wo kommt der callstack Punkt ? sieht aus wie Sie haben heap-Beschädigung hier.
Dies kann nicht im Zusammenhang mit deinem problem, aber warum benutzt du eine so alte compiler-version?
Wenn ich versuche zu tun, wiederholen, nichts happends, einfach alles hängt, bis ich den debugger beenden.
Ich schrieb vector deleting destructor, da-soweit ich weiß-dies ist der name der func erstellt der compiler für das löschen von arrays.
InformationsquelleAutor noplk | 2011-02-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist ein altes Problem in VC++ - in Bezug auf DLLs und Objekt-Arrays. Die Ursache ist eine falsche compiler-Optimierung, wie beschrieben von Microsoft.
http://support.microsoft.com/kb/121216/en-us
Bessere Nutzung der STL-Container, die nicht haben, das problem durch die Verwendung der Zuweisung.
InformationsquelleAutor Markus Kull
Einer Klasse in eine DLL ist extrem empfindlich, ohne viel Hilfe von Compilern. Schauen Sie sich diese Antwort für details, WARUM dies problematisch ist: Wie kann ich eine Funktion aufrufen einer C++ - DLL, die akzeptiert einen parameter vom Typ stringstream von C#?.
Kurze version: wenn die Klasse ein interface verwendet inline-code, erleben Sie potenzielle Probleme genau so. Alle Vorlagen-Objekt (wie
std::string
) enthalten.Ich würde vermuten, das ist, warum. Es ist ähnlich wie das problem @Mikael Persson schlägt.
InformationsquelleAutor tenfour
Ich denke, das ist ein klarer Fall von Zuweisung auf einen Haufen und löschen auf einem anderen (beachten Sie, dass delete[] hat für die Abfrage der heap für die Anzahl der Elemente im array, und wenn der Haufen sich nicht selbst enthalten, diese Zeiger, es wird wieder "Fehler" (nicht wirklich) und es wird davon ausgegangen, dass es nur ein element, und verwenden Sie die skalaren löschen statt). Ich denke, dass das problem, das Sie verloren war und versuchen, Kochen Sie ihn nach unten, um ein einfaches Beispiel-code. Ich würde vorschlagen, Sie Lesen dieser Artikel (es ist alt, aber die Löschung Technik ist immer noch sehr relevant, verwende ich eine variation dieser Technik selbst und es funktioniert wie ein Charme). Ein moderner Weg, dies zu tun, ist das Anhängen einer löschen-Funktion Zeiger auf einen smart-pointer (shared_ptr) , behandelt Ihr Objekt, auf diese Weise, indem Sie diese löschen-Funktion-Zeiger in der gleichen Zeit, wie Sie das Objekt in eine factory-Funktion, stellen Sie sicher, dass das delete aufgerufen wird, auf den gleichen Haufen, der es zugeteilt wurde.
InformationsquelleAutor Mikael Persson
Im Allgemeinen würde ich empfehlen, mit einem std::vector<ClassFromDLL> statt ClassFromDLL*. Konstruieren Sie vorbei in Größe. Die Löschung wird dann automatisch sein. Leider habe ich nicht viel Erfahrung mit delete[], weil ich lasse mir immer die standard-Bibliothek das für mich machen 😉
InformationsquelleAutor Martin Stone
Blick auf den code, ich würde davon ausgehen das Objekt wurde kopiert von der default-copy-ctor, das führt zu einer Doppel-deletion bug. Das ist Undefiniertes Verhalten. Es scheint zu arbeiten, aber Pause aufgrund von scheinbar nicht zusammenhängenden änderungen - etwa die Umstellung von einer LIB in eine DLL.
InformationsquelleAutor MSalters