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

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

问题描述

抱歉各位,我忘了提到这是在 VS2013 中编码的.

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;

然后我分配我的内存:

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;

最后,我希望释放内存(失败).我已经尝试按照 SO 上给出的一些答案失败.

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]);

在第一个 free 语句中给出了检测到堆损坏的错误.有什么建议吗?

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.

从代码外部数组大小 - 值/键索引"中的注释看来,您想为2 * HASH_TABLE_SIZE"大小的二维数组分配内存,而从 for 循环中断条件中的代码i

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".

假设您想为2 * HASH_TABLE_SIZE"分配内存,您可以将相同的概念应用于不同的维度.

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

维度2 * HASH_TABLE_SIZE"表示两行和 HASH_TABLE_SIZE 列.正确的分配步骤如下:

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

步骤 1:首先创建一个长度等于行数的 int 指针数组.

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 `*` 

这将创建两个大小的 int 指针 (int*) 数组,在外部数组分配的代码中,您为两个 int 对象分配了内存,如下所示2 * sizeof(int) 而你需要内存来存储地址.您需要分配的总内存字节应该是 2 * sizeof(int*)(这是一个糟糕的拼写错误).

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. ?- 表示垃圾值,malloc 不初始化分配内存
  2. 它分配了两个内存单元,每个单元可以存储int
  3. 的地址
  4. 在图片中,我假设 int* 的大小为 4 个字节.

另外,你应该注意到我没有对 malloc 函数返回的地址进行类型转换,因为它是隐式类型转换的 void* 是通用的,可以分配给任何其他类型的指针类型(实际上在 C 中我们应该避免类型转换,你应该阅读更多来自 我是否转换了 malloc 的结果?).

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?).

现在第 -2 步:为每一行分配内存作为数组中您需要的列数的数组,即 = HASH_TABLE_SIZE.所以你需要循环行数(不是 HASH_TABLE_SIZE)来为每行分配数组,如下所示:

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)); 
  //                                                    ^^^^^

现在在每一行中,你要为长度为 HASH_TABLE_SIZE 的整数数组存储 int 你需要内存字节 = 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:

示意图

        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

在图片中我假设 HASH_TABLE_SIZE = 4 并且 int 的大小 = 4 字节,注意地址的值 a

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

现在这些是正确的分配步骤.

Now these are correct allocation steps.

否则分配你的释放步骤是错误的!

Other then allocation your deallocation steps are wrong!

请记住,一旦您在某个指针上调用了 free,您就无法访问该指针(也可以通过其他指针访问 pr 内存),这样做会调用未定义的行为——这是一个可以在运行时检测到的非法内存指令,可能会导致——分段错误或检测到堆损坏.

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.

此外,这是一种为二维数组分配内存的方法,就像您尝试做的那样.但是有更好的方法为完整的 2D 数组连续分配内存,为此您应该阅读 "Allocate memory 2d array in function C"(对于这个链接的答案,我还给出了如何为 3D 数组分配内存的链接).

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天全站免登陆