【发布时间】:2013-05-08 12:40:47
【问题描述】:
有没有办法绕过operator new 的覆盖?
类似这样的:
void* ::operator new( std::size_t size ) {
void *p = ( ::operator new( size ) ); // But original, _not_ infinite recursion
// do stuff with p
return p;
}
背景:
我有一些遗留代码,我们最近切换到使用 Visual Studio 2012 进行编译。现在,当malloc 无法使用足够的内存块时,我们会随机崩溃。 (是的,代码到处都是小内存泄漏和其他不良行为。但不幸的是,彻底清理是不现实的,它大约是 500 000 SLOC。)
我目前的理论是,原因是几乎所有源文件都包含一个带有以下operator new 覆盖的标题:
void* ::operator new( std::size_t size ) {
void* p = malloc( size );
if( p == NULL )
throw;
// set memory to zero
memset( p, 0, size );
return p;
};
void* ::operator new[]( size_t count ) throw(std::bad_alloc) {
// try to allocate count bytes for an array
return (operator new(count));
}
delete 没有覆盖。
本质上,这意味着应用程序将使用malloc 的分配与使用delete 而不是free 的释放混合在一起。
首先尝试 Q&D 修复:
引入使用 free 的 delete 覆盖。但这只是部分帮助,因为有时包含订单和链接库仍然会搞砸。
第二次尝试 Q&D 修复: 删除覆盖。但不幸的是,将内存初始化为 0 是必要的。使用的旧编译器的遗产,它总是这样做,而假设 C++ 的编码器总是会这样做。
我知道 new() 会解决这个问题,但不幸的是,我不知道有什么好的方法可以在不手动检查所有源代码并更新它的情况下使用它。它也无助于实现不佳的类,这些类假定其所有成员在构造函数中没有这样做的情况下都被取消。
因此,我对 Q&D 修复的第三个想法: 正如这个问题所询问的那样,在覆盖中使用正常的 new 。
【问题讨论】:
-
在运算符 new 上使用
=delete。 8.4.3 标准的删除定义\可能会提供更多细节。 -
无论如何,您的全局
operator new很可能以malloc的形式实现(否则您在第一次调用delete时会崩溃)。所以这个覆盖唯一不同的是零填充内存。做你想做的事不太可能有帮助(即使有可能),因为当前版本已经做了完全相同的事情。为delete添加覆盖不太可能有帮助,因为当前版本已经做了完全相同的事情(尽管为了保持一致性我还是会这样做)。 你需要修复真正的内存错误。没有办法解决这个问题。 -
@n.m.,感谢您的评论。我检查了 Visual Studio 中包含的源文件,在我看来,
operator new没有在 MS C++ 中使用malloc实现。malloc和operator new都是用_heap_alloc实现的,但在我理解的一些簿记方面有所不同。 -
因此您需要将覆盖从标题中移出并放入适当的源文件中,并为
delete添加覆盖。世界上没有任何理由会搞砸任何事情。如果是这样,你需要解决这个问题,因为谁知道它会在哪里损害你的项目。
标签: c++ operator-overloading new-operator visual-c++-2012