2012-04-29 64 views
-3

此代码会导致与Visual Studio 2010相对应的堆损坏。 什么会导致堆损坏?这段代码的什么部分导致它?大内存分配大小的堆损坏C++

#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; 
} 
+1

什么是“合并”? –

+2

另外,你有一个内存泄漏;你永远不会释放'tmp'指向的内存。 –

+0

void merge(int * a,int a_size,int * b,int b_size,int * c) (int a_i = 0,b_i = 0,c_i = 0; c_i Nashwan

回答

3

怀疑memcpy是问题。您正在从tmp复制(n * 2 * sizeof(int))个字节,而您只为它分配n * sizeof(int)。

1

堆损坏只是意味着你已经分配了一块内存,然后在该块之外写入数据。通常这意味着你已经写过数组的末尾。

少量覆盖会打到内存分配后的“保护字”,因此运行时将检测到您的程序继续正常运行时的报告堆堆损坏。但是,如果您进一步编写代码,则可能会损坏一些其他关键数据(在程序尝试使用数据时导致未定义的结果)或运行内存映射的末尾并导致致命的访问冲突错误。

检查索引到你的数组始终范围0..Length-1

如果您不能计算使用的最大指标是什么,然后把一行代码在检查索引在这个范围内,如果不是,则进入调试器。即检查您传入merge/memcpy的值是否始终在范围内。 (有可能他们编写的元素太多了 - 对此的快速分配是分配一点比你“需要”更多的内存,但它显然不是正确的解决方案 - 你需要确保你只写入你打算的数据到)

1

你还没有为tmp分配足够的空间:

int* tmp = new int[2*n]; 

在合并代码for (..; ...; c_i++)递增看起来非常可疑了。

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

+0

不,我没有...谢谢你 – Nashwan