Freigeben von Speicher in einer anderen DLL
Habe ich eine EXE-Datei mit einer DLL-Datei, die mit einer anderen DLL-Datei. Diese situation hat sich ergeben:
DLL-Datei In 1:
class abc
{
static bool FindSubFolders(const std::string & sFolderToCheck,
std::vector< std::string > & vecSubFoldersFound);
}
In der DLL-Datei 2:
void aFunction()
{
std::vector<std::string> folders;
std::string sLocation;
...
abc::FindSubFolders(sLocation, folders)
}
Im release-Modus funktioniert alles einwandfrei. Aber im debug-Modus, ich komme mit ein Assertionsfehler in der Destruktor einer der std::strings
im Ordner vector (beim Ordner geht out of scope am Ende aFunction):
dbgheap.c : line 1274
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
Ich nehme an, dies ist, da der Speicher reserviert wurde auf DLL-Datei, 1 Haufen, aber freigegeben wird, die in DLL-Datei 2.
Den Kommentar in dbgheap.c
scheint ziemlich hartnäckig, dass das ein problem ist.
Warum ist das so ein problem, wenn es scheint gut zu funktionieren, wenn ich diese einfach ignorieren? Gibt es eine nicht-assertion-in Ermangelung einer Möglichkeit, dies zu tun?
- DONT . IGNORIEREN . BEHAUPTUNGEN
- NICHT. IGNORIEREN. ES. DAS IST. WARUM. I. BAT. =P
- Möchte nur wissen, warum es ein problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie sean schon gesagt hat, der release-build einfach ignoriert, dass die delete-Anweisung, so dass die beste man hoffen kann, ist ein Speicher-Leck.
Wenn Sie haben die Kontrolle über, wie die beiden DLL-Dateien kompiliert werden, stellen Sie sicher, dass Sie die Multi-threaded Debug DLL (/MDd) oder Multi-threaded DLL (/MD) Einstellungen für die runtime-Bibliothek. So, die beiden DLL-Dateien verwenden das gleiche runtime-Systems erhalten und teilen sich die gleichen heap.
Der Nachteil ist, dass Sie brauchen, um installieren Sie das runtime-system zusammen mit der Anwendung (Microsoft bietet einen installer dafür). Es funktioniert gut auf Ihre Entwicklung Maschine seit Visual Studio installiert das runtime-system auch, aber auf einer frisch installierten Maschine, es meldet fehlende DLL-Dateien.
Wahrscheinlich die release-Version hat das gleiche problem, aber release-builds nicht durchsetzen. Sie ignorieren einfach das problem. Sie könnte nie ein Problem. Oder sehen Sie vielleicht Beschädigung von Daten. Oder Sie möglicherweise zu einem Absturz. Vielleicht nur Ihre Nutzer erleben Fehler, Sie sind einfach nicht in der Lage, sich zu reproduzieren.
Nicht ignorieren CRT Behauptungen.
Sollten Sie immer die entsprechende deallocator (die, entspricht die Zuweisung verwendet, um mit zu beginnen). Wenn Sie mit der statischen CRT-Bibliotheken in Ihrem DLL-Dateien, DLL-Dateien, die mit unterschiedlichen Haufen. Sie können nicht Speicher freigeben über Haufen. Reservieren und freigeben eines Speicherblocks mit den gleichen heap.
Wenn Sie die freigegebene CRT-Bibliotheken in Ihrem DLL-Dateien, dann müssen Sie den gleichen Haufen, und können Sie zuordnen, in einer DLL-Datei und freigeben in einem anderen.
Andere sagt, das problem kann gelöst werden, indem sichergestellt wird, dass die CRT ist geteilt zwischen den beiden Modulen. Aber es gibt gemeinsame Szenarien, in denen dieser Vertrag ist schwer durchzusetzen.
Der Grund ist, dass macht Sie sicher, dass link gegen eine gemeinsame CRT funktioniert nicht, wenn die EXE-und DLL nicht link gegen die gleiche CRT - version (wie in 6.0, 7.0, 8.0). Zum Beispiel, wenn Sie eine DLL, die gebaut wurde, in VC6.0 und versuchen Sie es mit einem EXE build-in VS2010 Sie erhalten das gleiche Problem wie vorher. Die beiden Versionen der CRT wird geladen, Sie in Ihrem Prozess und werden jeweils Ihre eigenen Haufen für die Zuteilung, unabhängig davon, ob Sie Ihre EXE-und DLL verwenden 'shared' CRT, Sie wird nicht die gleiche sein.
Einer besseren Praxis für eine API wäre, um sicherzustellen, dass Objekte zugeordnet, die in einer Seite werden ebenfalls zerstört, die auf der gleichen Seite. Ich weiß, das klingt hässlich, aber es ist der einzige Weg, um sicherzustellen, dass eine DLL bleibt Binär-kompatibel.
Dies ist nur ein problem, wenn die Anwendung oder eine (oder mehrere) der DLL-Dateien verknüpft ist, gegen die statische version der standard-Bibliothek. Dies wurde gelöst, über ein Jahrzehnt von MS die Freigabe der shared library " - version der standard-Bibliothek. Dies ist, da jede version der standard-Bibliothek erstellen Sie eigene interne heap-und so mit mehreren Haufen müssen Sie den Speicher freizugeben, auf den richtigen Haufen. Durch die Verwendung der freigegebenen version der standard-Bibliothek, die Sie verwenden alle den gleichen heap.
Es ist gängige Praxis heutzutage für die Anwendung und alle DLL-Dateien aufgebaut sein sollten, um die Verwendung der dynamischen version der standard-Bibliothek.
Dem einzigen VORBEHALT zu der obigen ist, wenn Sie erstellen Sie Ihre eigenen heap und Speicher von diesem heap. Aber dies ist eine sehr spezialisierte Verfahren nur in seltenen Fällen (und wenn Sie genug verstehen um es zu benutzen, dann werden Sie nicht in der Lage, diese Frage).