Frage

Ich habe den folgenden Code:

std::string F()
{
  WideString ws = GetMyWideString();

  std::string ret;
  StringUtils::ConvertWideStringToUTF8(ws, ret);
  return ret;
}

Widestring ist eine Klasse von Drittanbietern, ebenso wie Stringutils. Sie sind eine Blackbox für mich. Der zweite Parameter wird mit Referenz übergeben.

Wenn ich durch den Debugger trete, die Linie return ret Wirft ein böses Popup (visuell C ++) und sagt, dass Haufen beschädigt werden kann. Bei näherer Prüfungskopie der zurückgegebenen Zeichenfolge ist in Ordnung, aber die Löschung von ret scheitert. ret Enthält den richtigen Wert vor der Rückgabe.

Was könnte die Konvertierungsfunktion möglicherweise tun, um dies zu verursachen? Irgendwelche Ideen zum Problem?

Aktualisieren:

  • Projekt selbst ist eine DLL
  • StringUtils ist eine LIB
  • Das Projekt wird gegen Multithread -CRT zusammengestellt (nicht Debug, nicht DLL)
  • Das Programm scheint bei der Ausführung außerhalb von Visual Studio gut zu laufen
War es hilfreich?

Lösung

  1. Wenn StringUtils separat zusammengestellt wurde (z. B. mit einer anderen Compiler -Version), können Sie einen Konflikt im Objektlayout haben.
  2. Wenn sich StringUtils in einer DLL befindet, müssen Sie sicherstellen, dass sowohl IT als auch das Hauptprogramm so kompiliert werden, dass die Standardbibliothek in einer DLL verwendet wird. Andernfalls hat jedes Modul (ausführbar und DLL) einen eigenen Haufen. Wenn Stringutils versucht, mit Daten in der Zeichenfolge zu spielen, die aus einem anderen Haufen zugewiesen wurde, passieren schlechte Dinge.

Andere Tipps

Der Designer von Stringutils hat eine sehr schlechte API entworfen. Keiner der Vorlagen -Standardbibliothekstypen sollte in der öffentlichen Schnittstelle der API verwendet werden. std::string ist inline ausgeblasen. Wenn der von Ihnen verwendete Compiler und die Bibliotheken nicht genau der gleiche Compiler und die Bibliotheken sind, die vom Implementierer von StringUtils verwendet werden, können die Typen und wahrscheinlich unterschiedlich sein. Grundsätzlich der Implementierer von Stringutils Die Schnittstelle nicht von der Implementierung trennen.

Eine Illustration des Problems. Angenommen, Sie verwenden MSVC 9.0 SP1 und ich verwende MSVC 8.0. Bei meinem Compiler könnte die Implementierung von STD :: String so aussehen:

class string
{
// : :  stuff
private:
  int someInt_;
  char* someBuf_;
};

... aber auf deinem Compiler könnte es anders aussehen:

class string
{
// : :  stuff
private: 

  void* impl_;
};

Wenn ich eine Bibliotheksfunktion schreibe:

void DoSomethingWithAString(std::string& str);

... und du nennst es, die sizeof(string) in Ihrem Code unterscheidet sich von der sizeof(string) in meinem Code. Die Typen sind nicht gleich.

Sie haben wirklich nur 2 Lösungen für Ihr Problem:

1) [bevorzugt] Holen Sie sich den Implementierer von StringUtils, seinen kaputten Code zu beheben.

2) Ersetzen Sie die von Ihrem Compiler verwendete Bibliothek, die für die von Stringutils Implementierern verwendete Bibliothek übereinstimmt. Möglicherweise können Sie dies erreichen, indem Sie denselben Compiler auf derselben Patch -Ebene wie der Implementierer verwenden, vorausgesetzt, er ersetzte die Implementierung der Standardbibliothek nicht.

Bearbeiten: 3) Eine dritte Option wäre die Beendigung der Verwendung von Stringutils. Ehrlich gesagt, das ist wahrscheinlich das, was ich tun würde.

Aus dem kleinen Code, den Sie zeigen, nehme ich an StringUtils::ConvertWideStringToUTF8() nimmt ein std::string& als zweiter Parameter. Angesichts dessen sehe ich nicht, wie Ihr Code eine Heap -Korruption verursachen kann.

Beachten Sie jedoch, dass die Verknüpfung von C ++ - Bibliotheken im Allgemeinen nur dann funktioniert, wenn der Code mit demselben Compiler und denselben Compiler -Einstellungen zusammengestellt wurde.

Ihre Verwendung von StringUtils und WideString lässt es so aussehen, als würden Sie C ++ Builder verwenden. Versuchen Sie, ein C ++ - Builder -Modul und ein visuelles C ++ - Modul zu mischen? Wenn ja, dann würden Sie definitiv die Probleme sehen, die Sie beschrieben haben.

Sie können kein visuelles C ++ übergeben std::string zu einer C ++ - Builder -Funktion, da der C ++ -Builder -Code angenommen wird, dass der Parameter C ++ Builder verwendet std::string Definition. Die Klassen haben möglicherweise unterschiedliche Felder, und die gemeinsamen Felder, die sie gemeinsam haben, sind möglicherweise in einer anderen Reihenfolge.

Auch wenn die Klassen die gleichen Definitionen haben, verwenden die Module dennoch unterschiedliche Speichermanager. Die aufgerufene Funktion vermittelt den neuen String -Inhalt mit seinem Speichermanager Speicher für den neuen String -Inhalt. Der Anrufer wird seinen eigenen Speichermanager verwenden, um den Inhalt der Zeichenfolge später zu befreien.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top