释放二维数组 - 堆损坏检测 [英] Freeing 2D array - Heap Corruption Detected

查看:174
本文介绍了释放二维数组 - 堆损坏检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:对不起球员,我忘了提,这是codeD在VS2013

我有一个全局声明结构:

  typedef结构数据//结构体,用于存储搜索和;排序运行时统计信息。
{
    INT ** a_collision;
} 数据;

数据DATA1;
 

我然后分配我的记忆中:

  data1.a_collision =(INT **)的malloc(的sizeof(int)的* 2); //声明外部数组大小 - 价值/关键指标。
的for(int i = 0; I< HASH_TABLE_SIZE;我++)
    data1.a_collision [I] =(INT *)malloc的(的sizeof(int)的* HASH_TABLE_SIZE); //声明内部数组的大小。
 

我然后初始化所有的元素:

  //初始化2D碰撞数据阵列。
的for(int i = 0;我2;我++)
对于(INT J = 0; J< HASH_TABLE_SIZE; J ++)
    data1.a_collision [I] [J] = NULL;
 

最后,我想释放内存(其无效)。我已经试过失败以下一些对SO已经给出了答案。

 免费(data1.a_collision);
的for(int i = 0; I< HASH_TABLE_SIZE;我++)
    免费(data1.a_collision [I]);
 

一个堆损坏检测到的错误,给出的第一个自由发言。有什么建议?

解决方案

有在code多的失误。逻辑错误如何分配内存的二维数组以及一些错别字。

这是在code注释外数组大小 - 价值/关键指标看起来你要分配内存2 * HASH_TABLE_SIZE大小的二维数组,而从code为循环断条件I< HASH_TABLE_SIZE;看来你要创建的尺寸HASH_TABLE_SIZE * 2。

数组

分配内存:

让我假设你要分配内存2 * HASH_TABLE_SIZE,就可以申请同一概念的不同维度。

的尺寸2 * HASH_TABLE_SIZE是指两行和HASH_TABLE_SIZE列。正确分配步骤,这将是如下:

步骤1:首先创建lenght的INT指针数组等于行数

  data1.a_collision =的malloc(2 * sizeof的(INT *));
// 2行^ ^你缺少`*`
 

这将产生两个大小INT指针( INT * )的数组,在您的code外阵列分配已分配的内存有两个 INT 对象作为 2 * sizeof的(INT)而你需要内存来存储地址。总内存字节,你需要分配应 2 * sizeof的(INT *)(这是可怜的错字错)。

  

您可以上图中配置为:

  343 347
                     + ---- + ---- +
data1.a_collision ---►| ? | ? |
                     + ---- + ---- +
 

     

      
  1. ? - 意味着垃圾的价值,的malloc不初始化分配内存
  2.   
  3. 它配备两个内存单元,每个可存储的地址 INT
  4.   
  5. 在图片我假定为int *的是大小为4个字节。
  6.   

此外,你应该注意到我并没有强制转换的malloc函数返回地址,因为它是隐式类型转换的void *是通用的,在C中可以分配给其他类型的指针类型的(其实我们应该避免类型转换,你应该阅读更多的来自难道我投malloc的结果? )。

现在步骤-2:分配内存,你需要在数组,它是= HASH_TABLE_SIZE每一行作为列的长度数量数组。所以,你需要循环的行(不适用于HASH_TABLE_SIZE)的数量来分配数组,每个行,如下:

 的for(int i = 0;我2;我++)
  // ^^^^通知
  data1.a_collision [I] =的malloc(HASH_TABLE_SIZE *的sizeof(INT));
  // ^^^^^
 

现在的你要存储每个行 INT 的长度整数 HASH_TABLE_SIZE 的数组,你需要的内存字节= HASH_TABLE_SIZE *的sizeof(int)的。你能想象它:

  

  data1.a_collision = 342
            |
            ▼201 205 209 213
        + -------- + + ----- + ----- + ----- + ----- +
 343 | | | ? | ? | ? | ? | //对于i = 0
        | | ------- | + ----- + ----- + ----- + ----- +
        | 201 | + -----------▲
        + -------- + 502 506 510 514
        | | + ----- + ----- + ----- + ----- +
 347 | | | ? | ? | ? | ? | //对于i = 1
        | 502 | ------- | + ----- + ----- + ----- + ----- +
        + -------- + + -----------▲

   data1.a_collision [0] = 201
   data1.a_collision [1] = 502
 

在画面我假设HASH_TABLE_SIZE = 4,大小INT = 4个字节,记地址的值a

现在这些都是正确的配置步骤。

释放内存:

其他然后分配的重新分配步骤是错误的!

记住,一旦你所谓的自由一些指针,你不能访问指针(通过其它指针也PR内存),这样调用不确定的行为,它是一个可以在运行时可能causes-被检测到非法内存指令分段故障以及或堆损坏检测。

正确的释放步骤的反如下分配:

 的for(int i = 0;我2;我++)
    免费(data1.a_collision [I]); //可用内存为每个行
免费(data1.a_collision); //免费行的地址。
 

更进一步,这是分配内存的二维数组像你试图做的方法之一。但还有更好的方法来不断分配内存完整的二维数组,这个你应该阅读分配内存二维数组中的函数C(这个链接的回答,我也给链接如何分配内存的3D阵列)。

EDIT: Sorry guys, I forgot to mention that this is coded in VS2013.

I have a globally declared struct:

typedef struct data //Struct for storing search & sort run-time statistics.
{
    int **a_collision;
} data;

data data1;

I then allocate my memory:

data1.a_collision = (int**)malloc(sizeof(int)*2);   //Declaring outer array size - value/key index.
for (int i = 0; i < HASH_TABLE_SIZE; i++)   
    data1.a_collision[i] = (int*)malloc(sizeof(int)*HASH_TABLE_SIZE);   //Declaring inner array size. 

I then initialize all the elements:

//Initializing 2D collision data array.
for (int i = 0; i < 2; i++)
for (int j = 0; j < HASH_TABLE_SIZE; j++)
    data1.a_collision[i][j] = NULL;

And lastly, I wish to free the memory (which FAILS). I have unsuccessfully tried following some of the answers given on SO already.

free(data1.a_collision);
for (int i = 0; i < HASH_TABLE_SIZE; i++)
    free(data1.a_collision[i]);

A heap corruption detected error is given at the first free statement. Any suggestions?

解决方案

There are multiple mistakes in your code. logically wrong how to allocate memory for two dimension array as well as some typos.

From comment in your code "outer array size - value/key index" it looks like you wants to allocate memory for "2 * HASH_TABLE_SIZE" size 2D array, whereas from your code in for loop breaking condition "i < HASH_TABLE_SIZE;" it seems you wants to create an array of size "HASH_TABLE_SIZE * 2".

Allocate memory:

Lets I assume you wants to allocate memory for "2 * HASH_TABLE_SIZE", you can apply same concept for different dimensions.

The dimension "2 * HASH_TABLE_SIZE" means two rows and HASH_TABLE_SIZE columns. Correct allocation steps for this would be as follows:

step-1: First create an array of int pointers of lenght equals to number of rows.

data1.a_collision =  malloc(2 * sizeof(int*)); 
//                   2 rows ^             ^ you are missing `*` 

this will create an array of int pointers (int*) of two size, In your code in outer-array allocation you have allocated memory for two int objects as 2 * sizeof(int) whereas you need memory to store addresses. total memory bytes you need to allocate should be 2 * sizeof(int*) (this is poor typo mistake).

You can picture above allocation as:

                      343  347  
                     +----+----+
data1.a_collision---►| ?  | ?  |
                     +----+----+

  1. ? - means garbage value, malloc don't initialize allocate memory
  2. It has allocated two memory cells each can store address of int
  3. In picture I have assumed that size of int* is 4 bytes.

Additionally, you should notice I didn't typecast returned address from malloc function because it is implicitly typecast void* is generic and can be assigned to any other types of pointer type (in fact in C we should avoid typecasting you should read more from Do I cast the result of malloc?).

Now step -2: Allocate memory for each rows as an array of length number of columns you need in array that is = HASH_TABLE_SIZE. So you need loop for number of rows(not for HASH_TABLE_SIZE) to allocate array for each rows, as below:

for(int i = 0; i < 2; i++)  
  //            ^^^^  notice   
  data1.a_collision[i] = malloc(HASH_TABLE_SIZE * sizeof(int)); 
  //                                                    ^^^^^

Now in each rows you are going to store int for array of ints of length HASH_TABLE_SIZE you need memory bytes = HASH_TABLE_SIZE * sizeof(int). You can picture it as:

Diagram

        data1.a_collision = 342
            |  
            ▼                       201   205   209    213  
        +--------+                +-----+-----+-----+-----+
 343    |        |                |  ?  |  ?  |  ?  | ?   |  //for i = 0
        |        |-------|        +-----+-----+-----+-----+
        | 201    |       +-----------▲
        +--------+                  502   506  510    514
        |        |                +-----+-----+-----+-----+
 347    |        |                |  ?  |  ?  |  ?  | ?   |  //for i = 1
        | 502    |-------|        +-----+-----+-----+-----+
        +--------+       +-----------▲

   data1.a_collision[0] = 201
   data1.a_collision[1] = 502

In picture I assuming HASH_TABLE_SIZE = 4 and size of int= 4 bytes, note address's valuea

Now these are correct allocation steps.

Deallocate memory:

Other then allocation your deallocation steps are wrong!

Remember once you have called free on some pointer you can't access that pointer ( pr memory via other pointer also), doing this calls undefined behavior—it is an illegal memory instruction that can be detected at runtime that may causes—a segmentation fault as well or Heap Corruption Detected.

Correct deallocation steps are reverse of allocation as below:

for(int i = 0; i < 2; i++)
    free(data1.a_collision[i]); // free memory for each rows
free(data1.a_collision); //free for address of rows.

Further more this is one way to allocate memory for two dimension array something like you were trying to do. But there is better way to allocate memory for complete 2D array continuously for this you should read "Allocate memory 2d array in function C" (to this linked answer I have also given links how to allocate memory for 3D arrays).

这篇关于释放二维数组 - 堆损坏检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆