在我的程序中,我有以下typedef:
typedef shared_ptr<IFrameObserver> IFrameObserverPtr;
以后,这行代码:
IFrameObserverPtr myObv(new MyObserver(cameras[0]))
。 。 。其中MyObserver是在IFrameObserverPtr的构造函数中创建的。问题是MyObserver类每次创建时都会创建一个6mB的位图,并且由于它永远不会被删除,这会导致非常严重的内存泄漏(此行每秒调用10次)。
我的问题很简单:如何明确删除新的MyObserver以避免这种内存泄漏?
关于我的内存泄漏是多么可怕的参考,在部分执行我的程序期间,这是我的任务管理器:
编辑:好的,我花了最后2个小时试图解决这个问题无济于事。做。 。 。
myObv.reset();
。 。 。没用。
这样每个人都可以看到MyObserver类中发生了什么,这里是:
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);
}
};
我已经尝试了所有我想到的东西来释放这些物体在创建时所产生的5.77 mB,而我无法弄清楚如何去做。
答案 0 :(得分:2)
假设您在评论中说typedef shared_ptr<IFrameObserver> IFrameObserverPtr
,那么当它超出范围时,它会减少引用计数。
所以有几种可能性:
所以第一个测试是确定是否:
{
IFrameObserverPtr myObv(new MyObserver(cameras[0]));
}
调用MyObserver析构函数。如果没有,则适用4或3。
如果该块泄漏了位图,则~MyObserver出错。
如果该块释放了位图,那么请查看保留该对象的其他内容。
通过编辑显示析构函数和创建位图hbm
的句柄的代码,显然析构函数不会破坏位图。
由于您使用CreateDIBitmap
创建了一个Win32 API调用hbm,您需要使用相应的Win32 API调用来释放它,msdn.microsoft.com / en-gb / library / windows / desktop / ...说是DeleteObject
,而不是仅仅在位图的句柄上使用C ++删除 - 您正在尝试删除句柄(这是void*
指针,因此是undefined behaviour)。你没有告诉Windows释放句柄指向的资源。
你可能也在泄漏图像数据,因为已经注释了试图释放图像数据 - 检查文档Frame::GetImage
(或任何调用是其实现的基础,如果它是你自己的代码)关于你是否需要调用任何可以解放的东西,或者它是否仍然属于框架。
答案 1 :(得分:0)
如果IFrameObserver
实现是为了拥有你传递给它的构造函数的MyObserver
,那么让它的析构函数删除它,然后确保IFrameObserver
被及时销毁。如果其他人应该拥有MyObserver
,请确保他们有一个指针并知道何时删除它。
如果你不知道谁应该拥有它,你需要弄明白。在C ++中实现内存管理的唯一方法是了解对象所有权和生命周期。完成整理后,shared_ptr
和unique_ptr
等内容可让您轻松实现。
答案 2 :(得分:0)
IFrameObserverPtr
的定义为typedef shared_ptr<T>(IFrameObserver) IFrameObserverPtr
问题是
MyObserver
类每次创建时都会创建一个6mB的位图它永远不会被删除
我认为您的意思是typedef shared_ptr<IFrameObserver> IFrameObserverPtr
,而您的计算机上有一个破损的复制/粘贴机制。
然后:
MyObserver
析构函数已损坏且必须修复,或MyObserver
析构函数及其基础等效IFrameObserver
析构函数未标记为virtual
。 MyObserver
对象本身在最后剩余的IFrameObserverPtr
超出范围时已经被销毁,所以当修复该销毁过程以消除泄漏时,你会没事的。< / p>