在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;
答案 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强制所有堆分配在页面末尾结束,这样超出会立即导致页面错误。