PDA

View Full Version : HEAP[VariousTests.exe]: Invalid Address specified to RtlValidateHeap.



hickscorp
1st April 2010, 11:21
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:
QString _internalString;

};

#endif
Test.cpp file:
#include "TestClass.h"

TestClass::TestClass () {
}
TestClass::~TestClass () {
}

QString TestClass::gimmeSomethinByCopy () const {
return QString("Toto");
}

const QString& TestClass::gimmeSomethinByRef () const {
return _internalString;
}

main.cpp file:
#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:[code]RELibOpt=__declspec(dllexport)
DEBUG
_DEBUG
QT_LARGEFILE_SUPPORT
QT_THREAD_SUPPORT
QT_CORE_LIB
QT_GUI_LIB

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

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++
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()

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.

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[]) {
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!
}
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++
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()
2nd case:
#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!
}
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++
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()

hickscorp
1st April 2010, 11:45
Problem solved! The library project for a reason i don't understand (Project generated using the VC Qt addin) was linking against the Qt debugging libs... Not the test project.
So when returning the copy QString, and then when freeing it, it may have been of 2 different sizes (Debug / Release).
Problem solved by using the same libraries.

fhdh
14th June 2017, 09:47
Hello
i Have the same probleme and i didn't understand how did you resolve it , can you help me please
i'm working in VB

d_stranz
20th June 2017, 01:13
i'm working in VB

Visual Basic? Why are you posting in a forum for Qt (which is C++ based) and in response to a 7 year old thread?