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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8186018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:08:02  来源:igfitidea点击:

How to properly replace global new & delete operators

c++windowsmemory-managementvisual-studio-2003

提问by void.pointer

First of all, there were at least 4-5 topics with a similar topic on SO. I read each of them and I don't feel they really help me with this specific issue. If someone else finds a duplicate question I apologize. I've done my share of searching before I posted this, as it seems like a very common question.

首先,至少有 4-5 个主题与 SO 上的主题相似。我阅读了其中的每一个,但我觉得它们并没有真正帮助我解决这个特定问题。如果其他人发现重复的问题,我深表歉意。在发布这个之前,我已经完成了我的搜索,因为这似乎是一个非常常见的问题。

I'm using Visual Studio .NET 2003 on Windows 7.

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

I have my own overloads of new/delete that point to my own custom calls to malloc() and free() for diagnostics. My new/delete overloads are in a header file which I've included in a few files.

我有自己的 new/delete 重载,指向我自己对 malloc() 和 free() 的自定义调用以进行诊断。我的新/删除重载位于我已包含在几个文件中的头文件中。

The problem is, the code base is pretty much spaghetti and there is no easy way to make sure these overloads get used by everything. There are includes to third party libraries that are black-box. We also use STL everywhere.

问题是,代码库几乎像意大利面条一样,没有简单的方法来确保所有东西都使用这些重载。有包含到第三方库的黑盒。我们也到处使用 STL。

In my tests I've found that STL is still mixing calls to my own new/delete and the standard MSVC new/delete calls.

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

It doesn't seem realistic to include my header file in thousands of other files, that would just take far too long. Can anyone offer some tips on how to properly and effectively overload new/delete globally so everything uses my custom memory manager?

将我的头文件包含在数以千计的其他文件中似乎不太现实,那只会花费太长时间。任何人都可以提供一些关于如何在全局范围内正确有效地重载 new/delete 以便一切都使用我的自定义内存管理器的提示吗?

回答by Kerrek SB

That's not how this works. You replacethe two operators, and this is done at linktime. All you need to do is write a single TU that definesthese operators and link it into the mix. Nobody else ever needs to know about this:

这不是它的工作原理。您替换两个运算符,这是在链接时完成的。您需要做的就是编写一个 TU 来定义这些运算符并将其链接到组合中。没有人需要知道这一点:

// optional_ops.cpp

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

In principle, there's no need for any header files to declare these functions (operator new, operator delete), since the declarationsof those two functions are already hardcoded into the language, if you will. However, the names std, std::bad_allocand std::size_tare notpredeclared, so you will probably want to include <new>or some other header to provide those names.

原则上,不需要任何头文件来声明这些函数 ( operator new, operator delete),因为如果您愿意,这两个函数的声明已经硬编码到语言中。然而,名称stdstd::bad_allocstd::size_t预先声明,所以你可能要包括<new>或一些其他的头,可以提供这些名称。

In C++11 and beyond, you can alternatively use decltype(sizeof(0))to get the size of the first parameter in a way that doesn't require any kind of library. C++11 also has a simpler exception model without dynamic exception specifications (which were finally removed from the language entirely in C++17).

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

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

回答by Extrunder

Also add these lines:

还添加这些行:

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