这不止一个问题。我需要处理C中的整数NxN矩阵A.如何在堆中分配内存?它是否正确?
int **A=malloc(N*sizeof(int*));
for(int i=0;i<N;i++) *(A+i)= malloc(N*sizeof(int));
我不完全确定上面代码的第二行是否应该用于启动内存。
接下来,假设我想访问元素A [i,j],其中i和j是从零开始的行和列索引。有可能通过取消引用指针** A以某种方式吗?例如,(A + n i + j)?我知道我在这里有一些概念上的差距,一些帮助将不胜感激。
答案 0 :(得分:2)
声明是正确的,但矩阵不会占用连续的内存空间。它是指针数组,其中每个指针都可以指向malloc
返回的任何位置。因此,像(A+ni+j)
这样的解决没有意义。
假设编译器支持VLA(在C11中成为可选项),定义连续矩阵的惯用方法是:
int (*matrixA)[N] = malloc(N * sizeof *matrixA);
通常,N
行和M
列的矩阵语法如下:
int (*matrix)[M] = malloc(N * sizeof *matrixA);
请注意,M
和N
都不必作为常量表达式给出(感谢VLA指针)。也就是说,它们可以是普通的(例如自动的)变量。
然后,要访问元素,您可以使用普通的indice语法,如:
matrixA[0][0] = 100;
最后,要为这些矩阵重新计算内存,请使用单free
,例如:
free(matrixA);
free(matrix);
答案 1 :(得分:2)
不完全确定上面代码的第二行是否应该用于启动内存。
它需要存在,因为它实际上为您需要的N
N
行分配int
行的空间。
第一个分配仅分配行索引指针。
访问元素A [i,j],其中i和j是从零开始的行和列索引。它可以通过取消引用指针**
来实现
当然,只是做
A[1][1]
访问元素第二行的第二个元素。
这与
相同*(*(A + 1) + 1)
与您无关的问题:
虽然您显示的代码是正确的,但是更加健壮的代码编码方式是:
int ** A = malloc(N * sizeof *A);
for (size_t i = 0; i < N; i++)
{
A[i] = malloc(N * sizeof *A[i]);
}
size_t
是索引的选择类型,因为它保证足够大,可以为编译代码的系统保存任何索引值。
您还要对malloc()
的两个调用添加错误检查,因为如果未能分配请求的内存量,它可能会返回NULL
。< / p>
答案 2 :(得分:1)
你需要了解2D和更高的数组在C 89中不能很好地工作。初学者书籍通常在一个很早的章节中引入2D数组,就在1D数组之后,这导致人们假设代表2-的自然方式尺寸数据是通过2D阵列。事实上,它们有许多棘手的特征,应该被认为是一种高级功能。
如果您在编译时不知道数组维度,或者数组很大,那么分配一维数组并通过逻辑访问几乎总是更容易
array[y*width+x];
所以在你的情况下,只需打电话
int *A;
A = malloc(N * N * sizeof(int))
A[3*N+2] = 123; // set element A[3][2] to 123, but you can't use this syntax
重要的是要注意使用平面阵列的建议只是一个建议,不是每个人都会同意它,并且在以后的C版本中2D阵列处理更好。但是我想你会发现这个方法有效最好的。