C - 动态矩阵分配:有些东西对我来说没有意义
C - dynamic matrix allocation: something doesn't make sense to me
我想知道,为什么这样做有效
// read n as matrix dimension, then:
int* M;
M = (int*)malloc(n * n * sizeof(int));
// cycle through each "cell" in the matrix and read a number with
scanf("%d", &M[i * n + j]);
这不是吗?
// read n as matrix dimension, then:
int** M;
M = malloc(n * n * sizeof(int));
// cycle through each "cell" in the matrix and read a number with
scanf ("%d", &M[i][j]);
我只是不明白。在这两种情况下,它们都应该是双指针,对吗?
案例 1 :-
int* M;
M = (int*)malloc(n * n * sizeof(int));
这里内存分配给M
,是单指针。假设您想将 5
整数存储到该内存中。所以看起来像
-------------------------------
| 10 | 20 | 30 | 40 | 50 |
-------------------------------
M M[0] M[1] M[2] m[3] M[4] <--- Its a 1D array, only one row of 5 int
案例 2 :-
int **M;
M = malloc(n * n * sizeof(int));
M[0][0] M[0][1]
| | | | ....... | | <---- If below one is not done then how will you store the numbers into these
----------- ----- ---------
| | | |
M[0] M[1] M[2] .... M[4] <--- didn't allocated memory for these rows or 1D array
| | | |
-----------------------------------
|
M <---- allocated memory for this
它不起作用,因为 M
是双指针并且您只为 M
分配了内存,而没有为 M[row]
分配内存。这就是为什么下面的声明不起作用。
scanf ("%d", &M[i][j]);
所以首先要让它工作像你所做的那样为M
分配内存
M = malloc(row*sizeof(*M)); /* row indicates no of rows */
然后为每一行分配
for(int index = 0 ;index < row;index++) {
M[index] = malloc(col * sizeof(*M[index])); /* col indicates number of columns */
}
并扫描矩阵输入
for(int index = 0 ;index < row;index++) {
for(int sub_index = 0 ;sub_index < col; sub_index++)
scanf("%d",&M[index][sub_index]);
}
并且一旦矩阵工作完成,对每一行使用 free()
释放动态分配的内存,以 避免内存泄漏 .
int **
应该指向 int*
。在这里你已经分配了一些内存 - 准确地说是 sizeof(int)*rows*cols
字节,然后你使用 M[i]
等。这里 M[i]
基本上是 *(M+i)
我们将访问 i*sizeof(int*)
偏移量来自 malloc
编辑的一个地址 return 但你分配给 rows*cols
int
而不是 int*
-s - 所以你最终会访问你应该访问的内存't(通常在 sizeof(int*) > sizeof(int)
的系统上)这将导致您出现未定义的行为。
那有什么办法呢?好分配 int*
-s。
int ** M = malloc(sizeof *M * rows);
if(!M){
perror("malloc");
exit(EXIT_FAILURE);
}
for(size_t i = 0; i < rows; i++){
M[i] = malloc(sizeof *M[i] * cols);
if(!M[i]){
perror("malloc");
exit(EXIT_FAILURE);
}
}
对于你的情况 rows = N
和 cols = N
。
这会给你一个锯齿状的数组,你可以像以前一样访问它。 malloc
负责检查它的 return 类型,并在您使用完它后释放内存。这样做。
在第一种情况下,您正在访问分配的内存块,并且您已经使用索引 i
和 j
实现了内存访问,让您自己体验访问内存的感觉,以防万一二维数组。所以在这里使用双指针是没有意义的。你所做的是合法的。
In both cases they should be double pointers
不,他们不应该。第一个与第二个不同。无论如何,它们并不表示同一件事。
其他答案(建议 M
的 malloc
和行的 n
malloc
s )是正确的,但不是分配 a 的最有效方法矩阵。但是,您可以仅通过一次 malloc
调用来分配矩阵,同时仍然允许您使用 M[i][j]
按行和列对其进行索引,如下所示:
int (*M)[cols] = malloc(rows * sizeof *M);
这将 M
声明为 指向长度为 cols
的 int
数组的指针,并请求 malloc
分配 rows
这样的数组的数量,这意味着你得到一个 rows * cols
int
s (sizeof *M == sizeof(int) * cols
).
的单个块
当 malloc
成功时,您可以使用 M
就好像它被声明为 int M[rows][cols]
这样您就可以使用
读入它
scanf("%d", &M[i][j]);
它看起来更复杂,但是将 M
分配为一个连续的内存块,这允许处理器优化对其的访问。
作为额外的奖励,您还可以通过一个电话免费使用它:
free(M);
这确实需要 C99 支持,或者至少支持 variable-length 数组,但矩阵本身不是合适的 variable-length 数组。它仍然是由 malloc
分配的,但是 M
的声明允许你像一个一样使用它。
我想知道,为什么这样做有效
// read n as matrix dimension, then:
int* M;
M = (int*)malloc(n * n * sizeof(int));
// cycle through each "cell" in the matrix and read a number with
scanf("%d", &M[i * n + j]);
这不是吗?
// read n as matrix dimension, then:
int** M;
M = malloc(n * n * sizeof(int));
// cycle through each "cell" in the matrix and read a number with
scanf ("%d", &M[i][j]);
我只是不明白。在这两种情况下,它们都应该是双指针,对吗?
案例 1 :-
int* M;
M = (int*)malloc(n * n * sizeof(int));
这里内存分配给M
,是单指针。假设您想将 5
整数存储到该内存中。所以看起来像
-------------------------------
| 10 | 20 | 30 | 40 | 50 |
-------------------------------
M M[0] M[1] M[2] m[3] M[4] <--- Its a 1D array, only one row of 5 int
案例 2 :-
int **M;
M = malloc(n * n * sizeof(int));
M[0][0] M[0][1]
| | | | ....... | | <---- If below one is not done then how will you store the numbers into these
----------- ----- ---------
| | | |
M[0] M[1] M[2] .... M[4] <--- didn't allocated memory for these rows or 1D array
| | | |
-----------------------------------
|
M <---- allocated memory for this
它不起作用,因为 M
是双指针并且您只为 M
分配了内存,而没有为 M[row]
分配内存。这就是为什么下面的声明不起作用。
scanf ("%d", &M[i][j]);
所以首先要让它工作像你所做的那样为M
分配内存
M = malloc(row*sizeof(*M)); /* row indicates no of rows */
然后为每一行分配
for(int index = 0 ;index < row;index++) {
M[index] = malloc(col * sizeof(*M[index])); /* col indicates number of columns */
}
并扫描矩阵输入
for(int index = 0 ;index < row;index++) {
for(int sub_index = 0 ;sub_index < col; sub_index++)
scanf("%d",&M[index][sub_index]);
}
并且一旦矩阵工作完成,对每一行使用 free()
释放动态分配的内存,以 避免内存泄漏 .
int **
应该指向 int*
。在这里你已经分配了一些内存 - 准确地说是 sizeof(int)*rows*cols
字节,然后你使用 M[i]
等。这里 M[i]
基本上是 *(M+i)
我们将访问 i*sizeof(int*)
偏移量来自 malloc
编辑的一个地址 return 但你分配给 rows*cols
int
而不是 int*
-s - 所以你最终会访问你应该访问的内存't(通常在 sizeof(int*) > sizeof(int)
的系统上)这将导致您出现未定义的行为。
那有什么办法呢?好分配 int*
-s。
int ** M = malloc(sizeof *M * rows);
if(!M){
perror("malloc");
exit(EXIT_FAILURE);
}
for(size_t i = 0; i < rows; i++){
M[i] = malloc(sizeof *M[i] * cols);
if(!M[i]){
perror("malloc");
exit(EXIT_FAILURE);
}
}
对于你的情况 rows = N
和 cols = N
。
这会给你一个锯齿状的数组,你可以像以前一样访问它。 malloc
负责检查它的 return 类型,并在您使用完它后释放内存。这样做。
在第一种情况下,您正在访问分配的内存块,并且您已经使用索引 i
和 j
实现了内存访问,让您自己体验访问内存的感觉,以防万一二维数组。所以在这里使用双指针是没有意义的。你所做的是合法的。
In both cases they should be double pointers
不,他们不应该。第一个与第二个不同。无论如何,它们并不表示同一件事。
其他答案(建议 M
的 malloc
和行的 n
malloc
s )是正确的,但不是分配 a 的最有效方法矩阵。但是,您可以仅通过一次 malloc
调用来分配矩阵,同时仍然允许您使用 M[i][j]
按行和列对其进行索引,如下所示:
int (*M)[cols] = malloc(rows * sizeof *M);
这将 M
声明为 指向长度为 cols
的 int
数组的指针,并请求 malloc
分配 rows
这样的数组的数量,这意味着你得到一个 rows * cols
int
s (sizeof *M == sizeof(int) * cols
).
当 malloc
成功时,您可以使用 M
就好像它被声明为 int M[rows][cols]
这样您就可以使用
scanf("%d", &M[i][j]);
它看起来更复杂,但是将 M
分配为一个连续的内存块,这允许处理器优化对其的访问。
作为额外的奖励,您还可以通过一个电话免费使用它:
free(M);
这确实需要 C99 支持,或者至少支持 variable-length 数组,但矩阵本身不是合适的 variable-length 数组。它仍然是由 malloc
分配的,但是 M
的声明允许你像一个一样使用它。