使用1个malloc调用为2d矩阵分配内存 [英] Allocating memory for 2d matrix using 1 malloc call

查看:120
本文介绍了使用1个malloc调用为2d矩阵分配内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

We can allocate memory for 2d matrix using 1 malloc call as
int (*a)[5];
int i,j;

a = malloc(sizeof(int *)* 5); //分配5个指针 并且每个指针都指向5个整数的数组

a=malloc(sizeof(int*) * 5); //allocating 5 pointers and each pointer points to an array of 5 ints

我们如何释放成功分配的内存? 使用free(a)会导致运行时错误

How can we free this memory allocated successfully? Using free(a) gives run-time error

使用 for(i = 0; i< 5; i ++) 免费(a [i]);

Using for(i=0;i<5;i++) free(a[i]);

免费(a);

这还会产生运行时错误

推荐答案

整个故事.

以前,我忽略了三种分配二维数组的其他方法.

Previously I ignored THREE other ways to allocate 2d arrays.

动态二维数组方法1:

如果您知道编译时的列数,则此方法有效.

This one works if you know the the number of columns at compile time.

#define CCOLS 200

int (*m)[CCOLS] = malloc(cRows * sizeof(*m));
m[iRow][iCol] = n; // sets the item at iRow*CCOLS + iCol

...

free(m);

之所以可行,是因为m被声明为指向CCOLS int数组的指针.编译器知道其大小并为您计算数学. m [iRow] = CCOLS整数数组.

This works because m is declared as a pointer to an array of CCOLS ints. The compiler knows its size and does the math for you. m[iRow] = an array of CCOLS ints.

您只能将此代码传递给具有以下签名的函数:

You can only pass this to functions with this signature:

foo(int (*m)[CCOLS]) { ... }

可能还有这个签名,具体取决于您的编译器和使用的开关:

and maybe this signature, depending upon your compiler and the switches you use:

foo(int m[][CCOLS]) { ... }

不是此签名:

foo(int **m) { ... }

由于内存布局和大小不同.

Since the memory layouts and sizes are different.

int m [] [CCOLS]看起来像这样:

int m[][CCOLS] looks like this:

+---------+---------+---------+---------+     
| m[0][0] | m[0][1] | m[0][2] | m[0][3] |     
+---------+---------+---------+---------+     
| m[1][0] | m[1][1] | m[1][2] | m[1][3] |     
+---------+---------+---------+---------+     
| m[2][0] | m[2][1] | m[2][2] | m[2][3] |     
+---------+---------+---------+---------+     
| m[3][0] | m[3][1] | m[3][2] | m[3][3] |     
+---------+---------+---------+---------+     

int ** m看起来像这样:

int **m looks like this:

+----+        +----+----+----+----+----+      
|m[0]|  --->  |    |    |    |    |    |      
+----+        +----+----+----+----+----+      
|m[1]|  --->  |    |    |    |    |    |      
+----+        +----+----+----+----+----+      
|m[2]|  --->  |    |    |    |    |    |      
+----+        +----+----+----+----+----+      
|m[3]|  --->  |    |    |    |    |    |      
+----+        +----+----+----+----+----+      

动态二维数组方法2(并非所有编译器都支持C99):

这与上一个相同,但是您不需要在编译时知道尺寸.

This one is the same as the previous but you don't need to know dimensions at compile time.

int cCols, cRows, iCol, iRow;
... set cRows, cCols somehow, they could be passed in as parameters also ...
int (*m)[cCols] = malloc(cRows * sizeof(*m));
m[iRow][iCol] = n; // sets the item at iRow*cCols + iCol

...

free(m);

您只能将此代码传递给具有以下签名的函数:

You can only pass this to functions with this signature:

foo(int cCols, m[][cCols])  {}

或这个

foo(int cRows, int cCols, m[cRows][cCols])  {}

如果您使用gcc,请参见信息.

If you use gcc, here is more info.

使用堆栈的动态二维数组方法3! (并非所有编译器都支持C99):

如果您对堆栈上的2d数组没问题,则可以完全避免使用malloc.

This lets you avoid malloc entirely if you are ok with your 2d array on the stack.

int cRows, cCols;
... set cRows, cCols somehow ...
int m[cRows][cCols];
m[iRow][iCol] = n; 

我认为您也可以通过这种方式声明全局变量.

I assume you could declare a global variable this way too.

将其传递给函数,方法与方法2相同.

You pass this to functions the same way as method 2.

动态二维数组方法4:

这是很多人使用的指针方法数组.

This is the array of pointers method that a lot of people use.

您使用一个malloc进行分配以提高效率.当然,您然后只能免费使用一个.仅当您拥有庞大的数组(其中连续内存成为问题)并发出问题时,您才想单独分配每行.

You use one malloc to allocate to be efficient. And of course you then only use one free. Only if you have HUGE arrays where contiguous memory becomes and issue, would you want to malloc each row individually.

int cCols = 10, cRows = 100, iRow;

// allocate:
// cCols*cRows*sizeof(int) = space for the data
// cRows*sizeof(int*) = space for the row ptrs
int **m = malloc(cCols*cRows*sizeof(int) + cRows*sizeof(int*));

// Now wire up the row pointers.  They take the first cRows*sizeof(int*) 
// part of the mem becasue that is what m[row] expects.
// we want each row pointer to have its own cCols sized array of ints.
// We will use the space after the row pointers for this.
// One way to calc where the space after the row pointers lies is to
// take the address of the nth + 1 element: &m[cRows].
// To get a row ptr, cast &m[cRows] as an int*, and add iRow*cCols to that.
for (iRow = 0; iRow < cRows; ++iRow)
    m[iRow] = (int*)&m[cRows] + iRow*cCols; 

// or 
for (p=(int*)&m[cRows] ; iRow = 0; iRow < cRows; ++iRow, p+=cCols)
    m[iRow] = p; 


// use it:
...
m[iRow][iCol] = 10;
...

// free it
free(m);

这篇关于使用1个malloc调用为2d矩阵分配内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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