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 个整数的数组
我们如何释放成功分配的内存?使用 free(a( 会导致运行时错误
用for(i=0;i<5;i++(免费(a[i](;
免费(a(;
这也会产生运行时错误
编辑:整个故事。
以前我忽略了其他三种分配 2D 数组的方法。
动态二维阵列方法 1:
如果您知道编译时的列数,则此方法有效。
#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 整数数组的指针。 编译器知道它的大小并为您进行数学运算。 m[iRow] = 一个 CCOLS 整数数组。
您只能将其传递给具有此签名的函数:
foo(int (*m)[CCOLS]) { ... }
也许还有这个签名,这取决于你的编译器和你使用的开关:
foo(int m[][CCOLS]) { ... }
不是此签名:
foo(int **m) { ... }
由于内存布局和大小不同。
int m[][CCOLS] 看起来像这样:
+---------+---------+---------+---------+
| 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 看起来像这样:
+----+ +----+----+----+----+----+
|m[0]| ---> | | | | | |
+----+ +----+----+----+----+----+
|m[1]| ---> | | | | | |
+----+ +----+----+----+----+----+
|m[2]| ---> | | | | | |
+----+ +----+----+----+----+----+
|m[3]| ---> | | | | | |
+----+ +----+----+----+----+----+
动态 2d 数组方法 2(并非所有编译器都支持 C99(:
这个与上一个相同,但你不需要在编译时知道维度。
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);
您只能将其传递给具有此签名的函数:
foo(int cCols, m[][cCols]) {}
或者这个
foo(int cRows, int cCols, m[cRows][cCols]) {}
如果您使用 gcc,请参阅此处。
动态二维阵列方法3使用STACK!(并非所有编译器都支持的C99(:
这样,如果您对堆栈上的 2D 数组感到满意,则可以完全避免 malloc。
int cRows, cCols;
... set cRows, cCols somehow ...
int m[cRows][cCols];
m[iRow][iCol] = n;
我假设你也可以通过这种方式声明一个全局变量。
将其传递给函数的方式与方法 2 相同。
动态二维阵列方法4:
这是很多人使用的指针数组方法。
您可以使用一个 malloc 进行分配以提高效率。 当然,您只能免费使用一个。 只有当你有巨大的数组,其中连续的内存变得和问题,你才想单独地对每一行进行malloc。
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);