gpt4 book ai didi

c++ - 尝试包装和覆盖全局运算符 new 时的递归调用

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:14:34 25 4
gpt4 key购买 nike

我已经有一段时间没有编写 C++ 程序了,在玩弄重载的全局运算符 newdelete 时遇到了一个奇怪的行为。问题的本质似乎是围绕默认全局 new 构建的包装器并驻留在 separate 源文件中尽管如此,调用在另一个(并单独编译)源文件中重载的 operator new

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

提前致谢,详情如下。

项目结构:

.
..
main.cpp
mem_wrappers.h
mem_wrappers.cpp

项目文件内容:

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;
}

mem_wrappers.h

#include <cstring>


void * default_arr_new_wrapper(size_t sz);

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);
}

符合 g++ main.cpp mem_wrappers.cpp --ansi --pedantic -Wall 运行时给 default_arr_new_wrapper 无限的 operator new[] > 反之亦然,调用结果如下:

overloaded new()[]

default_arr_new_wrapper()

overloaded new()[]

default_arr_new_wrapper()

...

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

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

编辑/更新

如果(如第一个答案和评论所暗示的那样)全局 operator new 仅通过在单个编译单元中重载它 [the operator] 就可以为整个可执行文件有效地重新定义,那么:

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

附言我知道 mallocfree 可以,并且在发帖之前已经尝试过它们(工作正常),但是,这种行为背后的原因是什么(如果我真的要无论如何包装默认的operator new?:))?

最佳答案

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

作为旁注,替换 是那些罕见的“不公平”语言功能之一,从某种意义上说,它通常不对用户可用。您不能在 C++ 中编写“可替换”函数。您不能编写任何行为与全局 operator newoperator new 的默认库实现行为相同的行为。 (替换是弱符号链接器概念的语言级表现)。

关于c++ - 尝试包装和覆盖全局运算符 new 时的递归调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1897006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com