gpt4 book ai didi

c++ - 函数不会抛出 bad_alloc 异常

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:51 24 4
gpt4 key购买 nike

我正在尝试从 Stroustrup 的 C++PL4 书中做一个练习。任务是:

Allocate so much memory using new that bad_alloc is thrown. Report how much memory was allocated and how much time it took. Do this twice: once not writing to the allocated memory and once writing to each element.

以下代码不会抛出 std::bad_alloc 异常。执行程序后,我在终端中收到消息“Killed”。

还有。以下代码在 ~4 秒后退出。但是当我取消注释内存使用消息时

// ++i;
// std::cout << "Allocated " << i*80 << " MB so far\n";

程序将运行几分钟。一段时间后,它打印出已经分配了 TB 的内存,但我没有看到系统监视器应用程序有太大变化。这是为什么?

我使用 Linux 和系统监视器应用程序来查看使用情况。

#include <iostream>
#include <vector>
#include <chrono>

void f()
{
std::vector<int*> vpi {};
int i {};
try{
for(;;){
int* pi = new int[10000];
vpi.push_back(pi);
// ++i;
// std::cout << "Allocated " << i*80 << " MB so far\n";
}
}
catch(std::bad_alloc){
std::cerr << "Memory exhausted\n";
}
}

int main() {
auto t0 = std::chrono::high_resolution_clock::now();
f();
auto t1 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t0-t1).count() << " ms\n";
}

最佳答案

在现代残酷的世界中,调用 new(以及 malloc() 甚至 brk())并不一定会分配内存.它只是(通过层链)向操作系统发送请求,操作系统分配一个虚拟内存区域(四舍五入为系统内存页)。因此只有对给定内存的后续访问才能执行实际分配。

此外,现代操作系统允许内存“过度使用”。有时(取决于操作系统及其设置)应用程序可能需要完全更多的内存,操作系统甚至在理论上可以分配,包括它的所有交换区域等,所有这些都没有任何可见的问题。看at this page例如。

这样做是因为在现实生活中,所有应用程序实际上同时 使用所有分配的内存的情况是非常不可能的。更常见的是,99.99..% 的时间,应用程序只使用部分内存并按顺序执行,因此操作系统有机会无缝地满足它们的请求。

为了增加机会实际导致内存分配错误,您可以访问刚刚分配的元素,但我不会再一次将其称为逐字保证,只是“关于增加可能性”。

在最坏的情况下,当这样的操作系统实际上发现它无法分配足够的(虚拟)内存时,因为太多的应用程序同时请求访问它们无缝分配的数据,操作系统内存管理器启动一个称为“OOM killer”的特殊程序只是试探性地(= 随机 :))杀死选择的应用程序。

所以现在依赖 bad_alloc 是个坏主意。有时您可以可靠地接收它(例如,当人为地使用 ulimit/setrlimit 限制您的应用程序时),但通常您的应用程序将在无法保证任何事情的环境中运行。只是不要成为内存 pig 并为休息祈祷:)

关于c++ - 函数不会抛出 bad_alloc 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32678285/

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