Heap-Beschädigung bei der Rückgabe aus der Funktion innerhalb einer dll
Habe ich eine Funktion mit einem Prototyp wie folgt:
void function(std::string str);
Diese Funktion in meiner main-Funktion in ein anderes Programm geladen und verwendet diese dll.
function("some string value here");
Bei der Rückkehr von dieser Funktion habe ich bekommen heap corruption Fehler:
Windows hat einen Haltepunkt ausgelöst program.exe.
Dies kann durch eine Korruption des heap-gibt einen bug in
Programm.exe oder eine der DLLs geladen sind.Diese können auch durch den Benutzer durch das drücken von F12 während
Programm.exe-Datei, die den Fokus hat.Dem Ausgabe-Fenster kann mehr diagnostische Informationen.
Herumspielen mit meinem code, den ich bemerkte ein paar seltsame Beobachtungen:
1. Wenn die Länge des übergebenen Strings in weniger als 11 Zeichen ich bekomme keine Fehler, sobald ich mehr Zeichen, die die Fehlermeldung angezeigt wird.
2. Wenn die änderung der Art der parameter von std::string
zu std::string&
der Fehler verschwindet. Die Idee der Verweis kam von hier.
3. Hab ich auskommentiert, die Körper der Funktion. Die Vorgänge dort haben nichts zu tun mit der Ausnahme hergestellt.
4. Ändern des Parameters type aus std::string
zu char*
auch das problem löst.
Was könnte die Ursache dieses Fehlers? Wie kann ich es lösen?
- Ich erinnere mich gelesen zu haben, dass der Speicher Zuweisung über die DLL-Grenze, kann schwierig sein - wahrscheinlich am besten, um das Update verwenden Sie disovered, d.h. übergeben Sie einen Verweis.
- Ist die dll und das Programm zusammengestellt mit der gleichen version von std c++ - Bibliotheken? Sowohl Ihr Programm & dll-Versionen oder sind Sie beide debug - Versionen-also einer von Ihnen ist nicht eine andere Art als die anderen?
- Die dll ist eigentlich ein anderes Projekt in meiner Projektmappe (VS 2008). Recht nicht ich bin mit beiden debug-Versionen.
- siehe stackoverflow.com/q/1344126/492336
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wahrscheinlich, wirst du sehen, stürzt ab, aufgrund der Tatsache, dass in der Windows-DLLs, die haben Ihren eigenen heap.
Beim kompilieren der Funktion, die der compiler generiert code für
std::string
's Destruktor, zu bereinigen seine Argumente. Dieser code gibt den zugewiesenen Speicher für die DLL-heap. Jedoch die Programm-EXE erzeugt auch seinen eigenen code fürstd::string
's Konstruktor, der das ordnet den code auf dem Programm-heap. Bei der Zuordnung auf einen Haufen und Kostenlose auf der anderen, undefinierten Verhalten tritt auf, und Sie Abstürzen.So, warum kleine Zeichenfolgen nicht Auslöser der Fehler - viele
std::string
Implementierungen von inline-small-strings in das struct selbst, um zu vermeiden, heap overhead. Wenn Ihr string ist klein genug, um fit, kein memory-Zuweisung brauchen, nehmen Sie Platz, und so geschieht es, um zu funktionieren scheinen... solange Sie die gleichen STL-version für beide EXE-und-DLL, und die Schwelle für inlining, die sich nie ändert.Um dieses Problem zu vermeiden, nicht Objekte durch Wert übergeben, um DLLs (es sei denn, Sie sind POD-Objekte), und nicht frei, ein Objekt in einer anderen DLL oder EXE-Datei, als es erstellt wurde. Vermeiden Sie die übergabe von STL-oder C++ - Bibliothek Objekte herum so gut, wie Ihre Umsetzung kann sich zwischen verschiedenen Versionen der C++ - compiler. Pass POD Objekte oder C primitive Typen wie
const char *
statt.Beim exportieren von DLL-Funktionen, ist es am besten, wenn Sie akzeptieren nur Integrale Datentypen, also int oder Pointer (nicht sicher über float und double).
Wenn Sie brauchen, um eine Zeichenfolge übergeben, übergeben Sie es als
const char *
, wenn Sie Sie brauchen, die DLL-Funktion einen string zurückgeben, pass auf die DLL einchar *
Zeiger auf eine pre-allocated buffer, in dem die DLL zu schreiben, wäre der string.Nie verwenden reservierten Speicher von der DLL, die außerhalb der DLL ' s eigenen Funktionen, und nie wertübergabe von Strukturen, die haben Ihre eigenen Konstruktor/Destruktor.
Wahrscheinlich haben Sie verbunden mit der statischen version der C-Laufzeit, es ist nie eine gute Idee, um eine DLL zu erstellen, die im Zusammenhang mit der statischen version der C-runtime. Dies kann viele Probleme verursachen, zum Beispiel in Ihrem Programm die EXE Speicher von privaten heap eines statischen C-Laufzeitbibliothek, dass es verbunden ist mit ihm, dann in der DLL, die Sie löschen möchten, die auf dem heap und erstellen Sie einen neuen heap(da, den Sie hinzufügen möchten einige Daten zu den input-string und es zum wachsen brauchen den Puffer), so verursacht es einen Fehler. Einfachste Ansatz ist die Verknüpfung aller Teile des Programms(EXE und DLL) mit der DLL-version der C-runtime, so dass Sie alle teilen die selben heap von MSVCRTXX.dll
std::string
undstd::vector
) oder schreiben Sie eine benutzerdefinierte Zuweisung, die Zuweisung von Speicher aus einem gemeinsamen Haufen, zum Beispiel mitHeapAlloc
undGetProcessHeap