尝试换行并覆盖全局运算符new时的递归调用

mlv*_*ljr 1 c++ operator-overloading new-operator

我没有编程的C++了一会儿,用重载全球运营商玩弄时遇到一个奇怪的行为newdelete.问题的本质似乎是围绕默认全局的包装器构建new并驻留在单独的源文件中,然而operator new 在另一个(并且单独编译)源文件中调用了重载.

为什么会这样,即我违反/滥用哪种语言规则/功能?

在此先感谢,详情如下.

项目结构:

.
..
main.cpp
mem_wrappers.h
mem_wrappers.cpp
Run Code Online (Sandbox Code Playgroud)

项目文件内容:

main.cpp中

#include "./mem_wrappers.h"
#include <iostream>
#include <cstring>


void* operator new[] (size_t sz) throw (std::bad_alloc) {
  std::cout << "overloaded new()[]" << std::endl;
    return default_arr_new_wrapper(sz);
}


int main() {
    const unsigned num = 5;
    int * i_arr = new int [num];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

mem_wrappers.h

#include <cstring>


void * default_arr_new_wrapper(size_t sz);
Run Code Online (Sandbox Code Playgroud)

mem_wrappers.cpp

#include <new>
#include <cstring>
#include <iostream>


void * default_arr_new_wrapper(size_t sz) {
    std::cout << "default_arr_new wrapper()" << std::endl;
    return ::operator new[](sz);
}
Run Code Online (Sandbox Code Playgroud)

遵守克++ main.cpp中mem_wrappers.cpp --ansi --pedantic -Wall运行时给人以无穷operator new[]default_arr_new_wrapper反之亦然调用导致以下输出:

overloaded new()[]

default_arr_new_wrapper()

overloaded new()[]

default_arr_new_wrapper()

...
Run Code Online (Sandbox Code Playgroud)

最后,在SO中(MS Visual Studio Express编译器的行为相似).

我使用的编译器:gcc版本3.4.2(mingw-special)MS Visual Studio 2008版本9.0.30729.1 SP.

编辑/更新

如果(作为第一个答案和评论建议),operator new只需在单个编译单元中重载[运算符],就可以有效地为整个可执行文件重新定义全局,然后:

是仅仅链接一个源重载全局的目标文件operator new使得任何应用程序或库改变它(好吧,让我们这样调用)内存分配策略?因此,这个重载运算符有效地为语言运行时提供了一个钩子(我的意思是在已经编译的 - 没有任何重载的新目标文件中使用那些链接器符号,是否只有一个new)?

PS我知道malloc 并且free会这样做,并且在发布之前已经尝试过它们(工作正常),但是,这种行为背后的原因(如果我实际上要包装默认值operator new怎么办?:))?

AnT*_*AnT 8

如果您阅读标准中的措辞,那么operator new在定义自己的函数时对全局函数所做的操作称为替换(不是重载而不是覆盖).大多数时候,当人们谈论改变全局operator new功能时,他们使用术语"重载"并将其new称为"操作员".当结果行为与操作符重载通常预期的行为不一致时,这通常会导致混淆.这显然是你的情况.您期望重载行为,但您真正得到的是替换:一旦您operator new在某个翻译单元中定义了一个替换版本的全局函数,它就适用于整个程序.(new并不是真正的运营商.)

作为旁注,替换是罕见的"不公平"语言特征之一,从某种意义上说,用户通常无法使用.你不能在C++中编写"可替换"函数.你不能编写任何与全局operator newoperator new行为的默认库实现方式相同的东西.(替换是弱符号的链接器概念的语言级表现).

  • @Chubsdad:我不明白你在说什么.GCC和MSVC都允许替换全局`operator new`. (2认同)