c++ - 重载的“operator new”如何导致无限循环?
问题描述
我正在阅读一本名为“Hands-On System Programming with C++”的书。它在第 320 页上说,重载new
运算符会导致无限循环,因此应该避免。
这些重载会影响所有分配,包括 C++ 库使用的分配,因此在利用这些重载时应小心,因为如果在这些函数内执行分配,可能会发生无限循环递归。例如,std::vector 和 std::list 等数据结构或 std::cout 和 std::cerr 等调试函数不能使用,因为这些工具使用 new() 和 delete() 运算符来分配内存.
那么,这段代码怎么会导致死循环,为什么不应该用cout
andvector
呢?这是书中的一段代码。我尝试使用vector
, cout
(在new
运算符内部)push_back
,但无法复制这种情况。那么,这究竟什么时候会发生呢?
void* operator new (size_t size){
if(size > 1000) page_counter++;
return malloc(size);
}
解决方案
只需告诉 astd::vector
分配一些内存operator new
就可以了:
void *operator new(std::size_t size) {
// std::vector<int>::reserve calls std::allocator<int>::allocate calls (this) operator new calls ...
std::vector<int>().reserve(999);
return std::malloc(size);
}
int main() {
int *p = new int(42);
// OFC, this is undefined behavior, so we *could* reach this, but... we don't, which means it definitely is UB
std::cout << "Shouldn't reach this!\n";
}
请注意, a) 仅构造 a 是不够的std::vector
,因为它可能无法分配。std::vector
通常仅在您以某种方式告诉它时才分配。当您尝试向其添加内容时,它会扩展,或者您可以用reserve
. b)您必须operator new
从某个地方调用才能触发循环(这里它在new
in内main
)。
推荐阅读
- sql - how to convert sql rows into columns with conditions
- mysql - 雄辩的关系查询不起作用
- java - 如何使用Java根据长度和空间拆分字符串
- react-native - 带有博览会框架的通知正文中的秒表
- codeigniter - CodeIgniter\Session\Exceptions\SessionException。会话:PHP 进程不可写入配置的保存路径“{0}”
- c - 如何在C中的两个数字之间生成随机数?(核心)
- javascript - 如何将排序添加到引导表卡片视图/自定义视图?
- python - 元组名称和编号列表作为参数并删除
- image - 如何从谷歌云平台的虚拟机中获取新添加的图像?
- sql - SQL左连接但只取列上的特定条件