我期望它不会抛出Bad_alloc

时间:2014-03-13 21:26:54

标签: c++ segmentation-fault out-of-memory

考虑这个简单的程序:

#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,这完全告诉我......没什么。 如何使我的程序能够防止段错?

1 个答案:

答案 0 :(得分:2)

这似乎是您环境中的一个错误,导致new[]的实现中出现整数溢出。实际上,您正在分配0个字节。它可能是this bug。 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的实现),则此错误可能仍然会影响您。