Bad_alloc没有在我期望的时候抛出

Bad_alloc not thrown when I expect it to

本文关键字:期望 候抛出 alloc Bad      更新时间:2023-10-16

考虑这个简单的程序:

#include <exception>
#include <iostream>
int main(void)
{
    const std::size_t size = 1<<31;
    int *a = NULL;
    try
    {
        a = new int[size];
    }
    catch (std::exception &e)
    {
        std::cerr << "caught some bad guy" << std::endl;
        return 1;
    }
    if (a == NULL)
    {
        std::cerr << "it's null, can't touch this" << std::endl;
        return 1;
    }
    std::cerr << "looks like 'a' is allocated alright!" << std::endl;
    for (size_t i = 0; i < size; i ++)
        std::cout << a[i] << " ";
    return 0;
}
论>
  • 我尝试分配一些荒谬的内存量:(1<<31) * sizeof(int) == 8GB
  • 我增加了安全检查
    • 捕获std::exception,在其他例外情况下应该捕获std::bad_alloc
    • 检查它是否不为空(即使这个检查实际上是有意义的,我需要a = new (std::nothrow) int[size] -但不管我如何分配内存,它不起作用)

环境
  • RAM安装:2GB
  • 操作系统:Debian
  • 架构:32位

问题是程序没有提前退出,而是这样做:

rr-@burza:~$ g++ test.cpp -o test && ./test
looks like 'a' is allocated alright!
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
(...many other zeros here...)
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0Segmentation fault

打印的零的数目正好是33790,这告诉我确切的…什么都没有。我怎样才能使我的程序防分段故障?

这似乎是您的环境中的一个错误,导致new[]实现中的整数溢出。实际上,您分配了0个字节。可能是这个虫子。c++ 03标准没有明确应该发生什么,在c++ 11中应该抛出std::bad_array_new_length

如果您需要支持此系统,您可以在分配之前检查是否有溢出的机会,例如:

size_t size_t_max = -1;
if (size > size_t_max / sizeof(int))
    throw ...;

如果你使用的库没有这样的检查(例如std::vector的实现),这个错误可能仍然会影响你。