Why does delete [] crash in my destructor?

I have a member variable
wchar_t * _message;

This array is allocated in the constructor,
_message = new wchar_t [messageLength];

But when I try to free the memory with delete in the destructor, it crashes with a a HEAP CORRUPTION error.

[code=c++]

class ExampleZero
{
public:
ExampleZero( wchar_t* cppMessage);
~ExampleZero(void);
private:
const wchar_t *_message;
};

ExampleZero::ExampleZero( wchar_t* cppMessage)
{
_message = NULL;
errno_t winError;
if (cppMessage == NULL){
fwprintf(stderr, L"Null pointer for string.\n");
return;
}
size_t messageLength = wcslen(cppMessage);
if (messageLength < 1){
fwprintf(stderr, L"string is empty or invalid.\n");
return;
}
try{
long address=NULL;
_message = new wchar_t [messageLength];
address = (long) _message;
fprintf(stderr,"%x",address);
}
catch(std::exception& e){
fprintf(stderr, e.what());
return;
}
if(_message == NULL){
return;
}
SecureZeroMemory((PVOID)_message,messageLength);

winError = wcscpy_s((wchar_t *)_message, messageLength+1, cppMessage);

}

ExampleZero::~ExampleZero(void)
{
if(_message != NULL){
try{
/* Why does it crash here? */
delete [] _message;
}
catch(std::exception& e){
fprintf(stderr, e.what());
}
_message=NULL;
}
}

/*******************/
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{

ExampleZero * example0;
example0 = new ExampleZero(L"I Live");
delete example0;
}

return nRetCode;
}
[/code]
Last edited on
Why are you using a C string instead of an std::wstring?
I'm using JNI and SWIG, both those use C strings. Both are really C packages, with only partial C++ support. The real code I'm using is largely machine generated, and I have to fix the generator.

http://www.swig.org/
http://java.sun.com/javase/6/docs/technotes/guides/jni/
So?
std::wstring::c_str().

Anyway, I can't read that. Re paste the code to fix the indentation.
I suspect you are not guarding against object copies. That is, your object is created -- producing a call to
26 _message = new wchar_t [messageLength];

Then your object is copied at some point (via the default copy constructor -- which simply produces a bitwise-copy of your object, pointers and all).

Then the copy is destroyed, which calls the destructor and delete[]s the _message.

Finally, the original is destroyed, which calls the destructor that tries to delete[] the _message again...


Make sure to guard against object copies...

Hope this helps.
Why is _message declared as a constant?? It is not constant. It is just a variable.

The variable messageLength is populated with a call to wcslen(). This function returns the number of characters, not the number of bytes. This is all good except to your call to SecureZeroMemory(). You are using messageLength as the second parameter. That is wrong because the second parameter expects the number of bytes, not the number of characters. The call should instead look like this:
 
SecureZeroMemory((PVOID)_message, messageLength * sizeof(wchar_t));


Other than the above (and an apparently unnecessary type cast in wcscpy_s()), I don't see much of a problem. I do think that the const declaration of _message might be triggering your problem because constants are allocated by the compiler and you shouldn't have to worry about deallocating them.
Topic archived. No new replies allowed.