Hello,
i'm developping a library and a test project to use the library. i have ran into a problem which i can't seem to solve, so i have simplified both the library and the test project, to be able to post an error-reproducible code here.
The TestClass.h file:
#ifndef TestClass_h
#define TestClass_h
#include <QString>
class RELibOpt TestClass {
public:
// CTor / DCTor.
TestClass ();
virtual ~TestClass ();
// Test methods.
QString gimmeSomethinByCopy
() const;
const QString& gimmeSomethinByRef () const;
private:
};
#endif
#ifndef TestClass_h
#define TestClass_h
#include <QString>
class RELibOpt TestClass {
public:
// CTor / DCTor.
TestClass ();
virtual ~TestClass ();
// Test methods.
QString gimmeSomethinByCopy () const;
const QString& gimmeSomethinByRef () const;
private:
QString _internalString;
};
#endif
To copy to clipboard, switch view to plain text mode
Test.cpp file:
#include "TestClass.h"
TestClass::TestClass () {
}
TestClass::~TestClass () {
}
QString TestClass
::gimmeSomethinByCopy () const { }
const QString& TestClass::gimmeSomethinByRef () const {
return _internalString;
}
#include "TestClass.h"
TestClass::TestClass () {
}
TestClass::~TestClass () {
}
QString TestClass::gimmeSomethinByCopy () const {
return QString("Toto");
}
const QString& TestClass::gimmeSomethinByRef () const {
return _internalString;
}
To copy to clipboard, switch view to plain text mode
main.cpp file:[code]#include <QCoreApplication>
#include "TestClass.h"
#pragma comment (lib, "RELibrary.lib")
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// Instanciate the DLL exposed class.
TestClass anObject;
// Scope creation, on purpose.
if (true) {
// The method "QString DLLExportedClass::giveMeSomethin()" returns a QString, so it's copied...
QString szTest = anObject.gimmeSomethinByCopy();
} // CRASH HERE.
// Scope creation, on purpose.
if (true) {
// The method "const QString& DLLExportedClass::giveMeSomethinInternalByRef() const" returns by ref!
const QString szTest = anObject.gimmeSomethinByRef();
} // NO CRASH HERE!
}[code]
The TestClass library is compiled using the options:
RELibOpt=__declspec(dllexport)
DEBUG
_DEBUG
QT_LARGEFILE_SUPPORT
QT_THREAD_SUPPORT
QT_CORE_LIB
QT_GUI_LIB
RELibOpt=__declspec(dllexport)
DEBUG
_DEBUG
QT_LARGEFILE_SUPPORT
QT_THREAD_SUPPORT
QT_CORE_LIB
QT_GUI_LIB
To copy to clipboard, switch view to plain text mode
The main.cpp (Test project) is compiled using the options:
RELibOpt=__declspec(dllimport)
DEBUG
_DEBUG
QT_LARGEFILE_SUPPORT
QT_THREAD_SUPPORT
QT_GUI_LIB
QT_CORE_LIB
RELibOpt=__declspec(dllimport)
DEBUG
_DEBUG
QT_LARGEFILE_SUPPORT
QT_THREAD_SUPPORT
QT_GUI_LIB
QT_CORE_LIB
To copy to clipboard, switch view to plain text mode
My setup is Windows, Visual Studio 2008, Qt OpenSource 4.6.2 (Qt/bin is in my path).
As you can see, my library is loaded, the class is instanciated, the methods are called WITHOUT ERROR.
But in the case of a return - by - copy QString (Or any other Qt object), i get the fault when exiting the scope the QString was retrieved.
If i invert the blocs in the main, the faulty one remains the same (The return by ref doesn't crash at exit of scope).
Call stack:
ntdll.dll!7c90120e()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96e139()
ntdll.dll!7c96e576()
ntdll.dll!7c9622e8()
kernel32.dll!7c85f9a7()
> msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x003e5cc8) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!free(void * pUserData=0x003e5cc8) Line 49 + 0xb bytes C++
QtCored4.dll!qFree(void * ptr=0x003e5cc8) Line 60 + 0xa bytes C++
QtCored4.
dll!QString::free(QString::Data * d
=0x003e5cc8
) Line
1108 + 0x9 bytes C
++ VariousTests.exe!main(int argc=1, char * * argv=0x003a3670) Line 16 C++
VariousTests.exe!__tmainCRTStartup() Line 266 + 0x19 bytes C
VariousTests.exe!mainCRTStartup() Line 182 C
kernel32.dll!7c817077()
ntdll.dll!7c90120e()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96e139()
ntdll.dll!7c96e576()
ntdll.dll!7c9622e8()
kernel32.dll!7c85f9a7()
> msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x003e5cc8) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!free(void * pUserData=0x003e5cc8) Line 49 + 0xb bytes C++
QtCored4.dll!qFree(void * ptr=0x003e5cc8) Line 60 + 0xa bytes C++
QtCored4.dll!QString::free(QString::Data * d=0x003e5cc8) Line 1108 + 0x9 bytes C++
QtCored4.dll!QString::~QString() Line 869 + 0x23 bytes C++
VariousTests.exe!main(int argc=1, char * * argv=0x003a3670) Line 16 C++
VariousTests.exe!__tmainCRTStartup() Line 266 + 0x19 bytes C
VariousTests.exe!mainCRTStartup() Line 182 C
kernel32.dll!7c817077()
To copy to clipboard, switch view to plain text mode
Output:
HEAP[VariousTests.exe]: Invalid Address specified to RtlValidateHeap( 00390000, 003E5CA8 )
Windows has triggered a breakpoint in VariousTests.exe.
This may be due to a corruption of the heap, which indicates a bug in VariousTests.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while VariousTests.exe has focus.
The output window may have more diagnostic information.
HEAP[VariousTests.exe]: Invalid Address specified to RtlValidateHeap( 00390000, 003E5CA8 )
Windows has triggered a breakpoint in VariousTests.exe.
This may be due to a corruption of the heap, which indicates a bug in VariousTests.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while VariousTests.exe has focus.
The output window may have more diagnostic information.
To copy to clipboard, switch view to plain text mode
Thanks,
Pierre.
[EDIT]So you can see what happens, here are two main.cpp and two stack when it crashes. You can clearly see that in both cases, it's when going out of the scope where the COPYed QString was returned that it crashes.[EDIT]
1st case:
#include <QCoreApplication>
#include "TestClass.h"
#pragma comment (lib, "RELibrary.lib")
int main(int argc, char *argv[]) {
// On instancie l'objet exposé de la DLL.
TestClass anObject;
// Création volontaire d'un scope.
if (true) {
// La méthode "QString DLLExportedClass::giveMeSomethin()" renvoie une QString, donc assignée en copie...
QString szTest
= anObject.
gimmeSomethinByCopy();
} // Ca plante!
// Création volontaire d'un scope.
if (true) {
// La méthode "const QString& DLLExportedClass::giveMeSomethinInternalByRef() const"...
const QString szTest
= anObject.
gimmeSomethinByRef();
} // Ca ne plante pas!
}
#include <QCoreApplication>
#include "TestClass.h"
#pragma comment (lib, "RELibrary.lib")
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// On instancie l'objet exposé de la DLL.
TestClass anObject;
// Création volontaire d'un scope.
if (true) {
// La méthode "QString DLLExportedClass::giveMeSomethin()" renvoie une QString, donc assignée en copie...
QString szTest = anObject.gimmeSomethinByCopy();
} // Ca plante!
// Création volontaire d'un scope.
if (true) {
// La méthode "const QString& DLLExportedClass::giveMeSomethinInternalByRef() const"...
const QString szTest = anObject.gimmeSomethinByRef();
} // Ca ne plante pas!
}
To copy to clipboard, switch view to plain text mode
Stack:
ntdll.dll!7c90120e()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96e139()
ntdll.dll!7c96e576()
ntdll.dll!7c9622e8()
kernel32.dll!7c85f9a7()
> msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x003e5cc8) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!free(void * pUserData=0x003e5cc8) Line 49 + 0xb bytes C++
QtCored4.dll!qFree(void * ptr=0x003e5cc8) Line 60 + 0xa bytes C++
QtCored4.
dll!QString::free(QString::Data * d
=0x003e5cc8
) Line
1108 + 0x9 bytes C
++ VariousTests.exe!main(int argc=1, char * * argv=0x003a3670) Line 16 C++
VariousTests.exe!__tmainCRTStartup() Line 266 + 0x19 bytes C
VariousTests.exe!mainCRTStartup() Line 182 C
kernel32.dll!7c817077()
ntdll.dll!7c90120e()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96e139()
ntdll.dll!7c96e576()
ntdll.dll!7c9622e8()
kernel32.dll!7c85f9a7()
> msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x003e5cc8) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!free(void * pUserData=0x003e5cc8) Line 49 + 0xb bytes C++
QtCored4.dll!qFree(void * ptr=0x003e5cc8) Line 60 + 0xa bytes C++
QtCored4.dll!QString::free(QString::Data * d=0x003e5cc8) Line 1108 + 0x9 bytes C++
QtCored4.dll!QString::~QString() Line 869 + 0x23 bytes C++
VariousTests.exe!main(int argc=1, char * * argv=0x003a3670) Line 16 C++
VariousTests.exe!__tmainCRTStartup() Line 266 + 0x19 bytes C
VariousTests.exe!mainCRTStartup() Line 182 C
kernel32.dll!7c817077()
To copy to clipboard, switch view to plain text mode
2nd case:
#include <QCoreApplication>
#include "TestClass.h"
#pragma comment (lib, "RELibrary.lib")
int main(int argc, char *argv[]) {
// On instancie l'objet exposé de la DLL.
TestClass anObject;
// Création volontaire d'un scope.
if (true) {
// La méthode "const QString& DLLExportedClass::giveMeSomethinInternalByRef() const"...
const QString szTest
= anObject.
gimmeSomethinByRef();
} // Ca ne plante pas!
// Création volontaire d'un scope.
if (true) {
// La méthode "QString DLLExportedClass::giveMeSomethin()" renvoie une QString, donc assignée en copie...
QString szTest
= anObject.
gimmeSomethinByCopy();
} // Ca plante!
}
#include <QCoreApplication>
#include "TestClass.h"
#pragma comment (lib, "RELibrary.lib")
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// On instancie l'objet exposé de la DLL.
TestClass anObject;
// Création volontaire d'un scope.
if (true) {
// La méthode "const QString& DLLExportedClass::giveMeSomethinInternalByRef() const"...
const QString szTest = anObject.gimmeSomethinByRef();
} // Ca ne plante pas!
// Création volontaire d'un scope.
if (true) {
// La méthode "QString DLLExportedClass::giveMeSomethin()" renvoie une QString, donc assignée en copie...
QString szTest = anObject.gimmeSomethinByCopy();
} // Ca plante!
}
To copy to clipboard, switch view to plain text mode
Stack:
ntdll.dll!7c90120e()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96e139()
ntdll.dll!7c96e576()
ntdll.dll!7c9622e8()
kernel32.dll!7c85f9a7()
> msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x003e5cc8) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!free(void * pUserData=0x003e5cc8) Line 49 + 0xb bytes C++
QtCored4.dll!qFree(void * ptr=0x003e5cc8) Line 60 + 0xa bytes C++
QtCored4.
dll!QString::free(QString::Data * d
=0x003e5cc8
) Line
1108 + 0x9 bytes C
++ VariousTests.exe!main(int argc=1, char * * argv=0x003a3670) Line 20 C++
VariousTests.exe!__tmainCRTStartup() Line 266 + 0x19 bytes C
VariousTests.exe!mainCRTStartup() Line 182 C
kernel32.dll!7c817077()
ntdll.dll!7c90120e()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96e139()
ntdll.dll!7c96e576()
ntdll.dll!7c9622e8()
kernel32.dll!7c85f9a7()
> msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x003e5cc8) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x003e5cc8, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!free(void * pUserData=0x003e5cc8) Line 49 + 0xb bytes C++
QtCored4.dll!qFree(void * ptr=0x003e5cc8) Line 60 + 0xa bytes C++
QtCored4.dll!QString::free(QString::Data * d=0x003e5cc8) Line 1108 + 0x9 bytes C++
QtCored4.dll!QString::~QString() Line 869 + 0x23 bytes C++
VariousTests.exe!main(int argc=1, char * * argv=0x003a3670) Line 20 C++
VariousTests.exe!__tmainCRTStartup() Line 266 + 0x19 bytes C
VariousTests.exe!mainCRTStartup() Line 182 C
kernel32.dll!7c817077()
To copy to clipboard, switch view to plain text mode
Bookmarks