C:正确释放多维数组的内存 [英] C: Correctly freeing memory of a multi-dimensional array

查看:22
本文介绍了C:正确释放多维数组的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有以下用于初始化多维数组的 ANSI C 代码:

Say you have the following ANSI C code that initializes a multi-dimensional array :

int main()
{
      int i, m = 5, n = 20;
      int **a = malloc(m * sizeof(int *));

      //Initialize the arrays
      for (i = 0; i < m; i++) { 
          a[i]=malloc(n * sizeof(int));
      }

      //...do something with arrays

      //How do I free the **a ?

      return 0;
}

使用**a后,如何正确地从内存中释放它?

After using the **a, how do I correctly free it from memory ?

[更新](解决方案)

感谢 Tim(和其他人)answer,我现在可以执行这样的函数来从我的多维数组中释放内存:

Thanks to Tim's (and the others) answer, I can now do such a function to free up memory from my multi-dimensional array :

void freeArray(int **a, int m) {
    int i;
    for (i = 0; i < m; ++i) {
        free(a[i]);
    }
    free(a);
}

推荐答案

好的,解释到底是什么顺序有很多混乱必要的 free() 调用必须在,所以我会试着澄清什么人们正在努力达到以及为什么.

OK, there's a fair deal of confusion explaining exactly what order the necessary free() calls have to be in, so I'll try to clarify what people are trying to get at and why.

从基础开始,释放已分配的内存使用 malloc(),您只需使用指针调用 free()你是由 malloc() 给的.所以对于这段代码:

Starting with the basics, to free up memory which has been allocated using malloc(), you simply call free() with exactly the pointer which you were given by malloc(). So for this code:

int **a = malloc(m * sizeof(int *));

你需要一个匹配的:

free(a);

对于这一行:

a[i]=malloc(n * sizeof(int));

你需要一个匹配的:

free(a[i]);

在类似的循环中.

这变得复杂的地方是这需要发生的顺序.如果您多次调用 malloc() 以获得几个不同的块内存,一般来说,你在什么时候调用 free() 的顺序并不重要你已经完成了他们.然而,顺序在这里很重要具体原因:您正在使用一块 malloced 内存来保存指向 malloc 其他内存块的指针.因为你必须不要尝试读取或写入内存后将其交还给free(),这意味着你将不得不释放块它们的指针存储在 a[i] 之前 你释放 a 块本身.带有存储在 a[i] 中的指针的各个块不依赖于每个块其他,因此可以按您喜欢的任何顺序免费d.

Where this gets complicated is the order in which this needs to happen. If you call malloc() several times to get several different chunks of memory, in general it doesn't matter what order you call free() when you have done with them. However, the order is important here for a very specific reason: you are using one chunk of malloced memory to hold the pointers to other chunks of malloced memory. Because you must not attempt to read or write memory once you have handed it back with free(), this means that you are going to have to free the chunks with their pointers stored in a[i] before you free the a chunk itself. The individual chunks with pointers stored in a[i] are not dependent on each other, and so can be freed in whichever order you like.

所以,把这一切放在一起,我们得到:

So, putting this all together, we get this:

for (i = 0; i < m; i++) { 
  free(a[i]);
}
free(a);

最后一个提示:在调用 malloc() 时,请考虑更改这些:

One last tip: when calling malloc(), consider changing these:

int **a = malloc(m * sizeof(int *));

a[i]=malloc(n * sizeof(int));

到:

int **a = malloc(m * sizeof(*a));

a[i]=malloc(n * sizeof(*(a[i])));

这是在做什么?编译器知道 a 是一个 int **,所以它可以确定 sizeof(*a)sizeof(int *) 相同.然而,如果稍后您改变主意并想要 chars 或 shorts 或 longs 或数组中的任何内容而不是 int s,或者您稍后调整此代码用在别的地方,你只需要改变剩下的引用上面第一行引用的 int 以及其他所有内容将自动适合您.这消除了可能性将来会被忽视的错误.

What's this doing? The compiler knows that a is an int **, so it can determine that sizeof(*a) is the same as sizeof(int *). However, if later on you change your mind and want chars or shorts or longs or whatever in your array instead of ints, or you adapt this code for later use in something else, you will have to change just the one remaining reference to int in the first quoted line above, and everything else will automatically fall into place for you. This removes the likelihood of unnoticed errors in the future.

祝你好运!

这篇关于C:正确释放多维数组的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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