此代码导致与Visual Studio 2010对应的堆损坏。 是什么导致堆腐败?这段代码的哪一部分导致了它?
#define size 65536
int main()
{
int* a = new int[size];//size is equal to
srand(time(NULL));
for(int i = 0 ; i < size; i++)
{
a[i]= 1 + rand() % 10;
}
for(int i = 0; (size / 2) / pow((double)2, i)>= 1; i++)
{
int n = pow((double)2, i);
int offset = 0;
for(int j = 0; j < (size / 2) / pow((double)2, i); j++)
{
int* tmp = new int[n];
merge(a + offset, n, a + offset + n, n, tmp);
memcpy(a + offset, tmp, n*2 * sizeof(int));
offset += pow((double)2, i+1);
}
}
for(int i = 0; i < size; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
system("PAUSE");
return 0;
}
答案 0 :(得分:3)
怀疑memcpy是问题所在。你正在从tmp复制(n * 2 * sizeof(int))个字节,而你只为它分配了n * sizeof(int)。
答案 1 :(得分:1)
堆损坏只是意味着您已经分配了一块内存,然后在该块之外写入数据。通常这意味着您已经写过数组的末尾。
少量的覆盖将触发在内存分配后放置的“保护字”,因此运行时将检测到报告堆损坏,同时程序继续运行正常。但是,如果进一步编写,可能会损坏其他一些关键数据(当程序尝试使用数据时导致未定义的结果)或运行内存映射的结尾并发出致命的访问冲突错误。
检查数组中的索引是否始终在0..Length-1
范围内如果无法计算所使用的最大索引数,那么请输入一行代码以检查索引是否在此范围内,如果不是,则进入调试器。即检查您传入merge / memcpy的值是否始终在范围内。 (很有可能他们写了一个元素太多了 - 一个快速的例子是分配比你“需要”更多的内存,但它显然不是正确的解决方案 - 你需要确保你只写你想要的数据到)
答案 2 :(得分:1)
您尚未为tmp
分配足够的空间:
int* tmp = new int[2*n];
合并代码for (..; ...; c_i++
)的增量看起来也很可疑。
你可能有一些错误,使用调试器或编写跟踪消息并检查发生了什么 - 验证你没有写出界限。