Sign in to follow this  
storage

Problems deallocating

Recommended Posts

storage    175
I'm getting this error message (MS VC++ 2005 Beta 2) when I'm running my application:
Unhandled exception at 0x1024be5b (msvcr80d.dll) in TestApp.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
It occurs here:
ctest.h:
...
		unsigned char *data;
...

ctest.cpp:
int CTest::Free()
{
	if (!this->data)
		return -1;

	delete this->data; // this line

	return 0;
}


I've also tried "delete[] this->data;" instead of "delete this->data;". How do I fix this? Thanks in advance! :)

Share this post


Link to post
Share on other sites
SiCrane    11839
It sounds like you are calling Free() on a bad pointer to object. Check to make sure that your object is valid when making the call.

Share this post


Link to post
Share on other sites
Endurion    5408
0xcdcdcdcd is a special value MSVC uses for uninitialized variables. You didn't use data before nor set it to any useful value.

In the constructor of your CTest class, set data to NULL in the initializer list.



CTest::CTest() :
data( NULL )
{
}


Variables have not, are not and will not be set to any value if you don't do so in a constructor.

Share this post


Link to post
Share on other sites
moeron    326
Also deleting a NULL ptr has no adverse affect. Take the following for example


foo *pFoo = 0;

delete pFoo; // no problems...

pFoo = new foo;

delete pFoo; // no problems

delete pFoo; // **BOOM**


Generally when delete causes a problem, its because you are attempting to delete memory that has already been deleted or otherwise the pointer is pointing to chode memory.

Share this post


Link to post
Share on other sites
storage    175
Thanks everyone! :)

I tried taking the class apart, and rebuild it from scratch, using the advice I was given. The class is a wrapper around Corona that loads the image to pixel data.

Constructors:

CTest::CTest() : data(0)
{
}

CTest::CTest(std::string filename) : data(0)
{
this->Load(filename);
}



Destructor:

CTest::~CTest()
{
this->Free();
}



New Free() method:

void CTest::Free()
{
if (!this->valid)
return;

if (!this->data)
return;

delete this->data; // this line
}



Here is the code in main.cpp that uses the class that crashes:

CTest *Image = new CTest;

Image->Load("box.png");

int w = Image->width;
int h = Image->height;
unsigned char *data= Image->getdata();

delete Image; // this line



I'm now given another error (in a message box, not the normal one):

Debug Assertion Failed!

Program: ...
File: dbgdel.cpp
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)



Here is the call stack:

msvcr80d.dll!operator delete(void * pUserData=0x02184960) Line 52 + 0x51 bytes C++
> TestApp.exe!CTest::Free() Line 51 + 0x18 bytes C++
TestApp.exe!main() Line 61 C++
TestApp.exe!mainCRTStartup() Line 558 + 0x19 bytes C
kernel32.dll!RegisterWaitForInputIdle() + 0x49 bytes


Thanks in advance!

Share this post


Link to post
Share on other sites
TDragon    679
At a guess, it would seem to mean that you're trying to delete memory that was not allocated by your program. That's all I can tell without seeing more of what's going on...

Share this post


Link to post
Share on other sites
storage    175
Quote:
Original post by TDragon
At a guess, it would seem to mean that you're trying to delete memory that was not allocated by your program. That's all I can tell without seeing more of what's going on...


Thanks! But I can't see how the memory is NOT allocated.

CTest::Load:

int CTest::Load(std::string filename)
{
corona::Image *img = corona::OpenImage(filename.c_str());

if (!img)
{
printf("failed to load image file\n");
return -1;
}

this->width = img->getWidth();
this->height = img->getHeight();
//this->data = new unsigned char[(this->width * this->height) * 4];
this->data = (unsigned char *)img->getPixels();

return 0;
}

Share this post


Link to post
Share on other sites
Lacutis    301
Perhaps your OpenImage function isn't returning a NULL if it fails to load the image? Post the contents of "OpenImage()" and maybe that will show us where the problem is.

My guess is that openimage returns a pointer to a temporary created inside the function, which is a valid address at that point, and later on you are trying to deallocate a pointer which points to memory that isn't valid anymore.

Also as a side note, I had a little chuckle with the thread title off the main page "trouble deallocating, by storage" ;)

Share this post


Link to post
Share on other sites
storage    175
Quote:
Original post by Lacutis
Perhaps your OpenImage function isn't returning a NULL if it fails to load the image? Post the contents of "OpenImage()" and maybe that will show us where the problem is.

My guess is that openimage returns a pointer to a temporary created inside the function, which is a valid address at that point, and later on you are trying to deallocate a pointer which points to memory that isn't valid anymore.

Also as a side note, I had a little chuckle with the thread title off the main page "trouble deallocating, by storage" ;)


Haha :)

OpenImage isn't written by me, it's a part of the Corona image loader (link), so I have no idea what's going on in there, unfortunately :(.

How can I copy the data OpenImage is pointing to, and then point to it, after it has been deleted? memcpy()? And if so, how do I use it? :)

Thanks!

Share this post


Link to post
Share on other sites
Lacutis    301
Duh, I just realised something.

The data pointer is pointing to the result of getpixels, which according to the api documentation is the internal pixel buffer of the image that was loaded. It belongs to the image.

So you create a new Image* to point to some image that was loaded from the disk, then you assign a pointer to its pixel buffer, and the function ends. Losing your link to the image. Then in the destructor you are trying to delete a pixel buffer belonging to another object.

That is what the issue is. Instead of storing a pointer to the pixel data, store the Image* in your class, and delete THAT in your destructor.

Does that make sense?

Share this post


Link to post
Share on other sites
storage    175
Thanks again! :)

Makes sense, but the reason why I can't store the Image* in my class is because the CTest class is defined in a headerfile, then you link a library to use the functions defined in the header.

Example:
If you want to use Corona you include ctest.h, and link ctest-corona.lib to the project.

If you want to use SDL_image you include ctest.h, and link ctest-sdl_image.lib.

And so on.

Thanks! :)

Share this post


Link to post
Share on other sites
storage    175
Tried memcpy() some without any success. Is there any other way to copy the pixel data from an Corona Image* to an "unsigned char*"?

I tried the following:

memcpy(this->m_pixeldata, img->getPixels(), sizeof(img->getPixels()));

and

memcpy(this->m_pixeldata, img->getPixels(), (this->m_width * this->m_height) * 4);


Any help? :)

Thanks in advance! :)

Share this post


Link to post
Share on other sites
Zahlman    1682
Nothing along those lines will help; you *have to* store the Image*, because the allocated pixel buffer *does not belong to you*.

Having an Image* as a data member of the class should not be a problem; just try it. You might have to forward-declare 'class Image;' in your header before class CTest, but that's all - you can always declare a *pointer to* something as a class data member, even without a definition of that thing, as long as you can convince the compiler that it's a thing that can be pointed at ;) (Rationale: To have a valid class definition, the compiler has to be able to calculate the size of instances, which in turn requires the size of each data member. The size of an included object is not known without that class definition, but the size of a pointer is always the same.)

Share this post


Link to post
Share on other sites
Lacutis    301
What zhalman said. Nothing you do will allow you to keep hold of that pixel buffer. You *have* to store an Image* . However, if I got what you are saying you use the same class to do either SDL or corona. That's fine, all you have to do is declare a base class with the functions that are in common, then inherit a new class for each of the two libraries.

Like so:


ctest.h:

#ifndef CTEST_H
#define CTEST_H
class CTest
{
public:
virtual ~CTest();

virtual void Load() = 0; // Declare Pure virtual function
virtual int GetWidth() = 0;
virtual int GetHeight() = 0;
}
#endif

ccortest.h:

#ifndef CCORTEST_H
#define CCORTEST_H

#include "corona.h" // whatever their header is.

class CCorTest : public CTest
{
public:
CCorTest();
~CCorTest();

void Load();
int GetWidth();
int GetHeight();
protected:
Image * m_Image;
}
#endif



And do the same with a CSDLTest class.

then in your main you can declare either one, and link to BOTH libraries.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this