在C ++中绕过operator new的覆盖

时间:2013-05-14 09:34:32

标签: c++ operator-overloading new-operator visual-c++-2012

有没有办法绕过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无法_heap_alloc足够的内存块时,我们会发生随机崩溃。 (是的,代码中充斥着小内存泄漏和其他不良行为。但不幸的是,彻底的清理是不现实的,它大约有50万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混合使用delete进行分配。

首先尝试Q& D修复: 介绍使用free的{​​{1}}替换。但这只是部分有帮助,因为有时包括订单和链接库仍然搞砸了。

第二次尝试Q& D修复: 删除覆盖。但遗憾的是,将内存初始化为0是必要的。使用旧编译器的遗产,总是这样做,而假设C ++的编码器将始终这样做。

我知道new()会处理这个问题,但不幸的是,我不知道有什么好方法可以使用它而无需手动浏览所有源代码并更新它。它对于实现不好的类也无济于事,这些类假定所有成员在构造函数中没有这样做而无效。

因此,我对Q& D的第三个想法是: 正如这个问题所述,使用覆盖中的普通new。

1 个答案:

答案 0 :(得分:2)

  

有没有办法绕过操作符new的覆盖?

我没有意识到这一点,但为什么不简单地在自定义函数中重新实现它,就像MS在基于_heap_alloc的实现中所做的那样,只是将自定义添加到它?

无论如何,只做一次或多次分配尝试不是MS做的事情:

http://msdn.microsoft.com/en-us/library/vstudio/we2zys4d.aspx

  

默认行为是执行循环。在循环内,   函数首先尝试分配所请求的存储

无论如何 - 我是第二个。发表评论

  

你需要修复真正的内存错误

这是自我解释;对于那些任何调试目的 - 请看看std :: set_new_handler。

顺便说一句 - 有些事我觉得你的代码很烦人

  • 运营商的明确资格
  • 没有抛出std :: bad_alloc而是在catch-block之外重新投掷

快乐黑客!

问候,S。

P.S .:所有:我不能“投票”这个问题,因为我有限的exp在这里,但我建议这样做。这是一个非常有趣的话题,并且制定得很好。