堆内存分配大小为C ++的堆损坏

时间:2012-04-29 16:30:30

标签: c++

此代码导致与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;
}

3 个答案:

答案 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++)的增量看起来也很可疑。

你可能有一些错误,使用调试器或编写跟踪消息并检查发生了什么 - 验证你没有写出界限。