运算符在窗口中的新重载

Operator new overloading in windows

本文关键字:重载 新重载 窗口 运算符      更新时间:2023-10-16

我正在尝试替换全局运算符new并删除。在 Linux 中,这工作正常,但在 windows( MSVC 10 ) 中,它有时会使用运算符 new 的系统版本进行分配,然后尝试使用我的运算符删除来释放它。由于我在分配时存储了一些上下文信息,因此我的运算符 delete 在释放期间期望相同。如何确保窗口始终接替我的操作员?

编辑:我尝试了各种东西。这些是宣言

//Global new and delete overload
void* operator new (std::size_t bytes) throw(...);
void operator delete(void* p) throw();
void* operator new( std::size_t size, const std::nothrow_t&) throw();
void operator delete( void* mem, const std::nothrow_t&) throw();
void* operator new[] ( std::size_t bytes) throw(...);
void operator delete[](void* p) throw();
void* operator new[]( std::size_t size, const std::nothrow_t&) throw();
void operator delete[](void* mem, const std::nothrow_t&) throw();
#ifdef WIN32
void *__CRTDECL operator new(std::size_t size) _THROW1(_STD bad_alloc);
#endif

这些是定义

#ifdef WIN32
void *__CRTDECL operator new(std::size_t bytes) _THROW1(_STD bad_alloc)
{
    void* p = edb::g_getCurrentMemoryContext()->alloc(bytes);
    if (p==0) // did malloc succeed?
        throw std::bad_alloc(); // ANSI/ISO compliant behavior
    return p;
}
#endif
void operator delete(void* p) throw()
{
    edb::MemContext::free(p);
}
void* operator new( std::size_t bytes, const std::nothrow_t&) throw()
{
    return edb::g_getCurrentMemoryContext()->alloc(bytes);
}
void operator delete(void* p, const std::nothrow_t&) throw()
{
    edb::MemContext::free(p);
}
void* operator new[] ( std::size_t bytes) throw(...)
{
    void* p = edb::g_getCurrentMemoryContext()->alloc(bytes);
    if (p==0) // did malloc succeed?
        throw std::bad_alloc(); // ANSI/ISO compliant behavior
    return p;
}
void operator delete[](void* p) throw()
{
    edb::MemContext::free(p);
}
void* operator new[]( std::size_t bytes, const std::nothrow_t&) throw()
{
    return edb::g_getCurrentMemoryContext()->alloc(bytes);
}
void operator delete[](void* p, const std::nothrow_t&) throw()
{
    edb::MemContext::free(p);
}
有时

它会接受我的定义,有时不会。

谢谢戈库尔。

覆盖C++中的全局新建/删除是一个焦油婴儿。 是的,它看起来很简单,但随后你一个又一个破例,你不断为自己挖一个越来越深的坑。

您获得"他们的新"和"您的删除"的原因是,您可能正在使用一些在加载之前已经加载并"链接"到现有新版本的 DLL。 他们分配对象,然后你应该删除它。 您可以尝试静态链接程序来解决此问题。

处理此问题的另一种方法是重构代码并将 new/delete 重写为基类,然后使所有类都继承自基类。 对于一个有很多类的大型项目来说很乏味,但它会消除为谁调用哪个新/删除的歧义。

如果您这样做是一种可能"便宜"的隔离内存泄漏的方法,请考虑其他方法。 看看是否有任何检测工具供应商(例如纯化)仍然有"2周"的试用或通过Valgrind运行您的Linux版本。