如果我使用delete或::delete,会触发C++异常。
当然,我可以不进行删除操作,程序运行良好,但这样会导致内存泄漏问题迅速增加。
我的代码如下(包括与gdi+相关的任何内容):
#include <windows.h>
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
namespace Gdiplus
{
using std::min;
using std::max;
}
#include <gdiplus.h>
#pragma comment (lib,"Gdiplus.lib")
namespace Infra
{
namespace Color
{
//more app code
void CrashingMethod(...)
{
Gdiplus::Bitmap* bitmap = Gdiplus::Bitmap::FromFile(PNG_PATH);
//read bitmap
int qpWidth = frameWidth / 16;
Gdiplus::Color color = Gdiplus::Color();
for (unsigned int y = 0, qy = (frameHeight / 16) - 1; y < frameHeight; y += 16, qy--)
{
for (unsigned int x = 0, qx = 0; x < frameWidth; x += 16, qx++)
{
bitmap->GetPixel(x, y, &color);
byte red = color.GetRed();
//do stuff with the red channel
}
}
delete bitmap; //this line will randomly crash. Not always, not in all machines
bitmap = NULL;
}
}
}
}
什么是正确的释放方法?我知道删除gdi+位图存在问题,但使用::delete的解决方案并没有使其变得更好。与我看到的解决方案不同,我不是使用new来创建位图,而是使用"FromFile"。此外,正如您所看到的,我没有使用"namespace Gdiplus",因此该命名空间不在作用域内,我需要显式引用它(这可能会改变事情)。
Gdiplus::
,并且包含了<gdiplus.h>
,但你却没有使用Gdiplus
命名空间?那你用的是什么替代品呢?如果你确定你没有使用这个命名空间,那就得看看你用的是什么替代品了。 - andlabsbitmap
设置为NULL
似乎是毫无意义的。编译器肯定会在任何情况下优化掉它。 - David Heffernannew
和delete
在不同的堆上操作时就会发生这种情况(请参见跨DLL边界传递CRT对象的潜在错误)。为了防止这种情况,你的应用程序必须动态链接到与GDI+使用相同的CRT。无关紧要的是,如果你不想让min
/max
被定义为宏,那么在包含Windows.h之前,可以#define NOMINMAX
。 - IInspectable