如何正确替换全局新建和删除运算符

How to properly replace global new & delete operators

本文关键字:删除 运算符 新建 全局 何正确 替换      更新时间:2023-10-16

(至少有4-5个主题在SO上有类似的主题。我每一本都读了,但我觉得它们对我这个特定问题没有真正的帮助)。

我在Windows 7上使用Visual Studio . net 2003。

我有我自己的new/delete重载,指向我自己对malloc()free()进行诊断的自定义调用。我的new/delete重载在一个头文件中,它包含在几个文件中。

问题是,代码库就像意大利面条一样,没有简单的方法来确保这些重载被所有东西使用。第三方库中有一些是黑盒的。我们还处处使用STL。

在我的测试中,我发现STL仍然混合调用我自己的new/delete和标准的MSVC new/delete调用。

将我的头文件包含在数千个其他文件中似乎是不现实的,那将花费太长时间。谁能提供一些技巧,如何正确和有效地重载新/删除全局,使一切使用我的自定义内存管理器?

不是这样的。替换两个操作符,这是在链接时间完成的。您所需要做的就是编写一个单独的TU,其中定义了这些操作符,并将其链接到组合中。没有人需要知道这件事:

// optional_ops.cpp
void * operator new(std::size_t n) throw(std::bad_alloc)
{
  //...
}
void operator delete(void * p) throw()
{
  //...
}
原则上,不需要任何头文件来声明这些函数(operator new, operator delete),因为如果您愿意的话,这两个函数的声明已经硬编码到语言中。然而,stdstd::bad_allocstd::size_t的名称是没有预先声明的,所以您可能需要包括<new>或其他一些头文件来提供这些名称。

在c++ 11及以后的版本中,您可以选择使用decltype(sizeof(0))以不需要任何库的方式获取第一个参数的大小。c++ 11还有一个更简单的异常模型,没有动态异常规范(最终在c++ 17中完全从语言中删除)。

void * operator new(decltype(sizeof(0)) n) noexcept(false)
{
  //...
}

还要加上以下几行:

void *operator new[](std::size_t s) throw(std::bad_alloc)
{
    // TODO: implement
    return NULL;
}
void operator delete[](void *p) throw()
{
    // TODO: implement
}