内存位置的未处理异常bad_alloc

时间:2014-04-07 03:06:52

标签: c++ bad-alloc

在c ++中,在分配内存时会发生bad_alloc,或者至少这是我所理解的,但现在我从数组中读取内存时出现此错误。我创建了数组:

int * possible = new int[ suma ];

然后我得到两个循环,我访问整个数组:

for( int i = 0; i < n - 1; i++ ){
    int rowWidth = (i - 1) < 0 ? 0 : permutationsNumber[i];
    for( int j = 0; j < permutationsNumber[i]; j++ ){
        possible[i * rowWidth + j ] = j;
    }
}

for( int i = 0; i < n - 1; i++ ){
    int rowWidth = (i - 1) < 0 ? 0 : permutationsNumber[i];
    for( int j = 0; j < permutationsNumber[i]; j++ ){
        std::cout << possible[i * rowWidth + j ] << "\n";
}

std::cout << possible[i * rowWidth + j ] << "\n";行中的第二个是我收到错误的地方。

我在Windows上编译代码,尝试使用3个不同的机器使用Windows 8和7,使用VS 2010,2012和2013并得到相同的错误。

当我在Mac上编译代码时,我没有错误,使用compileonline

我认为不重要的变量值是:

n = 4;
permutationsNumber = {4, 12, 24};
suma = 40;

2 个答案:

答案 0 :(得分:2)

您对bad_alloc的理解有点不正确。当新运算符无法分配所请求的内存量时,bad_alloc将抛出此new。如果您向suma发送极大值,则会发生这种情况的情况并不少见。

例如,如果catch throw无法初始化,可能会发生这种情况。

您应该在调试器(gdb中为std::vector)中启用首次异常处理,并验证抛出异常的位置以及程序请求的内存量。

您可能正在观察的是无效的内存引用。您可以替换代码以使用at()并使用#include<cassert> ... const int idx = i * rowWidth + j; assert(idx >= 0); assert(idx < suma); possible[idx] = j; 方法访问元素。如果您错误地访问了超出范围的元素,这将引发异常。

或者,添加如下的断言:

{{1}}

如果断言触发(可能会),您现在已经确认您的阵列太小或索引无效。

答案 1 :(得分:1)

你正在破坏程序的堆。第一对for循环的最后一次传递将写入possible[71],但它实际上只有40个插槽。

它不一定立即崩溃的原因是内存保护通常在整个页面上运行(x86上为4KB)。除非你的缓冲区恰好落在页面末尾,否则很可能是数组末尾的许多位置都会落在与数组末尾相同(有效)的页面上,因此写入它们可能不会立即导致错误

在Windows上,您可以使用gflags utility强制所有堆分配在页面末尾结束,这样超出会立即导致页面错误。