Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何恰当地替换全球新产品和服务;删除运算符_C++_Windows_Memory Management_Visual Studio 2003 - Fatal编程技术网

C++ 如何恰当地替换全球新产品和服务;删除运算符

C++ 如何恰当地替换全球新产品和服务;删除运算符,c++,windows,memory-management,visual-studio-2003,C++,Windows,Memory Management,Visual Studio 2003,首先,至少有4-5个主题与类似的主题如此。我读了每一本书,但我觉得它们在这个具体问题上并没有真正帮助我。如果其他人发现重复的问题,我道歉。在我发布这篇文章之前,我已经做了我的部分搜索,因为这似乎是一个非常常见的问题 我正在Windows7上使用VisualStudio.NET2003 我有自己的new/delete重载,指向我自己对malloc()和free()的自定义调用以进行诊断。我的new/delete重载位于一个头文件中,我已经在几个文件中包含了这个头文件 问题是,代码库几乎是意大利面条

首先,至少有4-5个主题与类似的主题如此。我读了每一本书,但我觉得它们在这个具体问题上并没有真正帮助我。如果其他人发现重复的问题,我道歉。在我发布这篇文章之前,我已经做了我的部分搜索,因为这似乎是一个非常常见的问题

我正在Windows7上使用VisualStudio.NET2003

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

问题是,代码库几乎是意大利面条,没有简单的方法确保所有东西都使用这些重载。第三方库的包含是黑盒的。我们在任何地方都使用STL

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


将我的头文件包含在数千个其他文件中似乎不现实,这将花费太长的时间。有没有人能提供一些建议,说明如何正确有效地在全局范围内重载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
),因为这两个函数的声明已经硬编码到语言中,如果您愿意的话。但是,名称
std
std::bad_alloc
std::size_t
没有预先声明,因此您可能需要包含
或其他一些标题来提供这些名称

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

还要添加以下行:

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

如果在预编译的标题中全局定义运算符,则应覆盖最基本的内容。或者,如果用于检测内存泄漏,您可以使用CRT堆函数。链接器不会抱怨重复的定义吗?我认为ODR适用于这里。更不用说我们构建了120个DLL,我必须在每个DLL项目中链接它。我想这还是比其他选择更好。@RobertDailey:不,特例,标准中包括,弱引用,等等。前几天我在GCC中报告了一个与此相关的错误,所以在最新版本中,它甚至可以用于
-fwhole程序
-flto
等等(请参阅和。)`@罗伯特戴利:该标准涵盖了用户定义替换函数,因此没有违反ODR。编译器通过使标准函数成为“弱”引用来实现这一点,如果找到另一个同名符号,链接器将覆盖这些引用。是的,在Windows上,如果不将它们链接到每个DLL中,就无法为整个程序提供替换的new/delete函数。或者至少强制DLL导入这些函数,但我不确定这是否有效。我认为DLL以这种方式工作是不幸的。在其他平台上,当共享库在程序启动时链接时,它们通常遵守与静态链接的翻译单元相同的规则,因此如果您的程序替换了“新建/删除”,共享库也将得到这些替换。您可能还希望覆盖“不抛出”版本的
new
,它有第二个参数<代码> const STD::NojultT&< /Cuff>(C++标准的一部分)
void *operator new[](std::size_t s) throw(std::bad_alloc)
{
    // TODO: implement
    return NULL;
}
void operator delete[](void *p) throw()
{
    // TODO: implement
}