我期望它不会抛出Bad_alloc

rr-*_*rr- 5 c++ out-of-memory segmentation-fault

考虑这个简单的程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

评论

  • 我尝试分配一些荒谬的内存:(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
Run Code Online (Sandbox Code Playgroud)

打印的零数正好是33790,这正好告诉我......什么都没有.如何使我的程序具有段错误?

zch*_*zch 2

这似乎是您环境中的一个错误,它会导致new[]. 实际上,您分配了 0 个字节。可能就是这个bug。C++03 标准没有明确说明应该发生什么,在 C++11 中std::bad_array_new_length应该抛出。

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

size_t size_t_max = -1;
if (size > size_t_max / sizeof(int))
    throw ...;
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用的库没有此类检查(例如 的实现std::vector),此错误可能仍然会影响您。