c++ - 在存在 DEBUG_NEW 宏的情况下重载 operator new
问题描述
在 MFC 项目中,我使用了一个外部库TTL重载 operator new
. 我的问题是我有内存泄漏,我想利用DEBUG_NEW
. 但是,我只能在DEBUG_NEW
注释掉的情况下编译它,否则我会收到以下错误。
下面进行演示。当 Visual Studio 项目作为带有 MFC 标头的控制台应用程序时,它是一个 MCVE 。
// The problem is when this is uncommented
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
struct HandleId
{
HandleId() {}
void* operator new (size_t t) {
return HandleId::operator new(t, 0, 0, 0);
};
void* operator new (size_t t, int, const char* file, int line) {
HandleId* tmp = (HandleId*)calloc(1, t);
return tmp;
};
void operator delete (void* v) {
free(v);
}
};
namespace hed
{
struct Node : public virtual HandleId
{
Node() {};
Node(double x, double y, double z = 0.0) {}
};
}
struct DtmNode : public hed::Node
{
DtmNode() {};
DtmNode(short pntRef, double x, double y, double z)
: hed::Node(x, y, z)
{};
};
int main()
{
DtmNode* pNode = new DtmNode(0, 1.0, 2.0, 3.0);
return 0;
}
DEBUG_NEW
未注释上述编译失败(VS2019)。
错误 C2661:
HandleId::operator new
: 没有重载函数需要 3 个参数
到目前为止,我一直使用注释掉的宏。但我现在确实希望在调试版本中使用它,原因很明显,它有助于在调试期间捕获内存泄漏。DtmNode
是我可以改变的课程。HandleId
并且hed
命名空间属于库。
我的问题:
- 有没有办法在
DEBUG_NEW
未注释的情况下编译它? - 或者,有没有办法告诉在 _DEBUG 模式下
DtmNode
不要使用重载operator new
,以便DEBUG_NEW
按照“正常”使用?
解决方案
你的第一个问题的答案是“不”。
您可以通过使用#pragma push_macro/pop_macro 选择性地取消定义 new 来编译这类东西:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
...
int main()
{
#pragma push_macro("new")
#undef new
DtmNode* pNode = new DtmNode(0, 1.0, 2.0, 3.0);
#pragma pop_macro("new");
return 0;
}
它不允许您使用 MFC 的调试分配器跟踪库中的对象(为此,您必须完全替换库的分配器)。但它至少可以让你的程序在不匹配的 operator new 存在的情况下工作。
推荐阅读
- python - 在 Python 中,如何从 raw_input 中添加键和值的字典?米
- c# - 如何更改 Xamarin.Forms 中标签的字体系列?
- entity-framework - 使用 LINQ 寻找下一个免费价值
- swift - 如何用参数记录枚举案例?
- mysql - 在 PhpMyAdmin 中运行时,WHERE IN 给我不同的结果
- postgresql - 失败: npm install --save @nestjs/typeorm typeorm postgres
- azure - 仅在应用服务 Azure 上传出数据
- xml - 使用 xsl 在多次出现时连接特定的 XML 标记元素内容
- javascript - 如何使用 es6 或 lodash 将对象中的对象转换为数组
- artificial-intelligence - 给蒙特卡洛搜索的结果赋予更大的权重并减少转弯获胜是否有意义?