如何正确替换全局new和delete运算符

问题描述 投票:53回答:2

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

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

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

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

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

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

c++ windows memory-management visual-studio-2003
2个回答
74
投票

这不是这个工作原理。您替换了两个运算符,这是在链接时完成的。您需要做的就是编写一个定义这些运算符的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)
{
  //...
}

34
投票

还添加以下行:

void *operator new[](std::size_t s) throw(std::bad_alloc)
{
    // TODO: implement
    return NULL;
}
void operator delete[](void *p) throw()
{
    // TODO: implement
}
© www.soinside.com 2019 - 2024. All rights reserved.