In my program I have the following typedef:
typedef shared_ptr<IFrameObserver> IFrameObserverPtr;
And, later, this line of code:
IFrameObserverPtr myObv(new MyObserver(cameras[0]))
. . . in which MyObserver is created in the constructor of IFrameObserverPtr. The problem is that the MyObserver class creates a 6mB bitmap each time it gets created, and since it's never getting deleted, this causes a pretty severe memory leak (this line gets called 10 times a second).
My question is short and simple: How do I explicitly delete the new MyObserver to save myself from this memory leak?
For a reference as to how utterly horrible my memory leak is, here is my task manager during a partial execution of my program:
EDIT: Okay I've spent the last 2 hours trying to fix this to no avail. Doing . . .
myObv.reset();
. . . didn't work.
Just so everyone can see what's going on inside the MyObserver class, here it is:
class MyObserver : public IFrameObserver
{
public:
HBITMAP hbm;
BITMAPINFOHEADER* bi;
MyObserver(CameraPtr pCamera) : IFrameObserver(pCamera) {};
~MyObserver(){delete hbm;}
HBITMAP GetBMP()
{
return hbm;
}
void FrameReceived ( const FramePtr pFrame )
{
DbgMsg(L"Frame Received\n");
//////////////////////////////////////////////////////////////////////////
////////// Set Bitmap Settings ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//fileheader
BITMAPFILEHEADER* bf = new BITMAPFILEHEADER;
bf->bfType = 0x4d42;
bf->bfSize = 6054400 + 54;
bf->bfOffBits = 54;
//infoheader
bi = new BITMAPINFOHEADER;
bi->biSize = 40;
bi->biWidth = 2752;
bi->biHeight = -733;
bi->biPlanes = 1;
bi->biBitCount = 24;
bi->biCompression = 0;
bi->biSizeImage = 6054400;
bi->biXPelsPerMeter = 2835;
bi->biYPelsPerMeter = 2835;
bi->biClrUsed = 0;
bi->biClrImportant = 0;
//image data in VmbPixelFormatMono8
VmbUchar_t* imageData;
pFrame->GetImage(imageData);
//////////////////////////////////////////////////////////////////////////
////////// Output File to .bmp ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BITMAPINFO* bmi;
bmi = (BITMAPINFO*)bi;
HDC hdc = ::GetDC(NULL);
hbm = CreateDIBitmap(hdc, bi, CBM_INIT, imageData, bmi, DIB_RGB_COLORS);
delete bf;
delete bi;
//free(imageData); //doesn't work, crashes
//delete imageData; //doesn't work, crashes
imageData = NULL; //doesn't crash, but I don't think this frees the memory
DeleteObject(hdc);
}
};
I've tried everything I can think of to free the 5.77 mB this objects makes when it's created, and I cannot figure out how to do it.
Assuming typedef shared_ptr<IFrameObserver> IFrameObserverPtr
as you say in your comment, then it will decrement the reference count when it goes out of scope.
So there are several possibilities:
So the first test is to determine whether this:
{
IFrameObserverPtr myObv(new MyObserver(cameras[0]));
}
calls the MyObserver destructor. If not, then 4 or 3 will apply.
If that block leaks the bitmap, then ~MyObserver is faulty.
If that block frees the bitmap, then look into what else is retaining the object.
With your edit showing the destructor and the code which creates the bitmap for which hbm
is the handle, it's obvious that the destructor does not destroy the bitmap.
Since you create hbm with CreateDIBitmap
, a Win32 API call, you need to release it with the corresponding Win32 API call, which msdn.microsoft.com/en-gb/library/windows/desktop/… says is DeleteObject
, rather than just using C++ delete on the handle to the bitmap - you're trying deleting the handle (which is a void*
pointer so is undefined behaviour ). You're not telling Windows to free the resource the handle points to.
You possibly are also leaking the image data, since there are commented out attempts to free it - check the documentation Frame::GetImage
(or whatever call underlies its implementation if it's your own code) as to whether you have to call anything to free that, or whether it remains owned by the frame.
If the IFrameObserver
implementation is meant to own the MyObserver
you're passing to its constructor, get its destructor to delete it and then make sure IFrameObserver
gets destroyed promptly. If someone else is supposed to own the MyObserver
make sure they have a pointer and know when to delete it.
If you don't know who's supposed to own it, you need to figure it out. The only way to get your memory management right in C++ is to understand object ownership and lifecycles. Once you get that sorted out, things like shared_ptr
and unique_ptr
should allow you to implement it quite easily.
an
IFrameObserverPtr
has the definitiontypedef shared_ptr<T>(IFrameObserver) IFrameObserverPtr
The problem is that the
MyObserver
class creates a 6mB bitmap each time it gets createdit's never getting deleted
I assume you meant typedef shared_ptr<IFrameObserver> IFrameObserverPtr
and your computer has a broken copy/paste mechanic.
Then either:
MyObserver
destructor is broken and must be fixed, or MyObserver
destructor and its base equivalent the IFrameObserver
destructor were not marked virtual
. The MyObserver
object itself will already be destroyed when the last remaining IFrameObserverPtr
to it goes out of scope, so when that destruction process is fixed to remove the leak, you'll be fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.