如何正确取代全球新的&删除运算符

时间:2011-11-18 16:58:29

标签: c++ windows memory-management visual-studio-2003

首先,至少有4-5个主题在SO上有类似的主题。我读了他们每个人,我觉得他们真的没有帮我解决这个具体问题。如果其他人发现重复的问题我道歉。在我发布之前,我已经完成了我的搜索工作,因为这似乎是一个非常常见的问题。

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

我有自己的new / delete重载,指向我自己的malloc()和free()的自定义调用。我的新/删除重载在头文件中,我已将其包含在几个文件中。

问题是,代码库几乎是意大利面,没有简单的方法可以确保所有东西都能使用这些重载。包括第三方库是黑盒子。我们到处都使用STL。

在我的测试中,我发现STL仍在混合调用我自己的新/删除和标准的MSVC新/删除调用。

将我的头文件包含在数千个其他文件中似乎不太现实,这需要花费太长时间。任何人都可以提供一些关于如何正确有效地重载全局/删除全局的提示,以便所有内容都使用我的自定义内存管理器吗?

2 个答案:

答案 0 :(得分:74)

这不是这个如何运作的。您替换这两个运算符,这是在 link 时完成的。您需要做的就是编写一个定义这些运算符并将其链接到混合中的单个TU。没有人需要知道这个:

// optional_ops.cpp

void * operator new(std::size_t n) throw(std::bad_alloc)
{
  //...
}
void operator delete(void * p) throw()
{
  //...
}

原则上,不需要任何头文件来声明这些函数(operator newoperator 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)
{
  //...
}

答案 1 :(得分:34)

同时添加以下行:

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