如何在C语言中动态定义矩阵

3
我创建了一个程序,可以从外部文本文件中打印二维矩阵。如果我定义静态矩阵,比如A[10][10],我的程序就能工作。但是我想要动态分配内存。
当我尝试使用下面的代码时:
int **A = (int **)malloc(N * N * sizeof(int));

以下是错误信息:
未处理的异常 0x00AC159B 在 dataStructures4.exe 中: 写入位置 0xCDCDCDCD 的访问冲突
此问题出现在以下循环中:
for(i=0; i<N; i++){
    for(j=0; j<N; j++){
        A[i][j] = -1;
    }
}

我认为我无法正确生成动态矩阵。 我应该如何修改我的代码?

指向指针的指针并不等同于整数数组。 - Kerrek SB
1
我认为这个问题与http://stackoverflow.com/questions/22186294/i-am-having-trouble-passing-a-multidimensional-variable-array-to-a-function-in-c相似,你可以去看看。数组更像是结构体。因此,如果你想要访问它们,你应该将第二维看作一个结构体:int *A[10] - QJGui
6个回答

8
您可以动态地创建2D数组,其实就是一个指向int*指针的块,这些指针又分别指向一个int类型的块。
所以有两个步骤:
1)让A指向第一个int*块的开头位置。
int **A = (int **)malloc(N * sizeof(int*));

2) 每个指针都指向一块 int 数组的第一个元素

for(i=0; i<N; i++){
    A[i] = (int *)malloc(N * sizeof(int));
}

5

使用指向特定大小数组的指针:

您可以使用 #define 定义 N,或使用变量:

int n = 10 ;
int (*A)[n] = malloc(n * n * sizeof(int));

这样可以获得一块连续的内存空间。


很遗憾,int (*A)[N] 中的 N 必须在编译时知道,这与他所期望的不符。 - Filipe Gonçalves
2
@FilipeGonçalves 不,你错了。你可以毫不费力地做到这一点(至少从c99开始)。我的证明(没有时间搜索规范)http://ideone.com/bW4Qeo - this
1
抱歉,我的错。回答很好。我知道C99允许可变长度数组,只是当时没想到。+1 - Filipe Gonçalves
1
好的,但是他为什么一开始不使用2D VLA呢? - Filipe Gonçalves
2
@self。你的回答肯定使用了可变长度数组(VLAs)。A 是指向一个可变长度数组的指针。如果编译器不支持 VLAs,似乎是这种情况,这将无法工作。 - Filipe Gonçalves
显示剩余8条评论

1
记住,A[i][j]*(*(A+i)+j) 是一样的。你的代码出现了问题,因为 *(A+i) 解引用了一个无效的未初始化指针。这发生在这一行:
A[i][j] = -1;

另一种选择是使用动态分配指针数组,其中每个元素指向另一个动态分配的数组。您可以这样做:
int **array = malloc(N*sizeof(*array));
for (int i = 0; i < N; i++)
    array[i] = malloc(N*sizeof(*array[i]));

/* Use array[i][j]... */

请注意,内存布局与二维数组非常不同,但表达式array[i][j]会做你想要的事情 - 它会“看起来”像你有一个二维数组。

1

单独分配每一行,就像这样:

int **A = (int **)malloc(N * sizeof(int*));

for(i=0; i<N; i++){
    A[i] = (int *)malloc(N * sizeof(int));
}

1

与数组相同,二维矩阵具有连续的地址空间。因此在理论上是有方法实现这一点的。

int m = 2;
int n = 4;
int *a = malloc(m*n*sizeof(int));
int **b = malloc(m*sizeof(int*));
for(int i=0, i<m, i++)
{
    b[i] = a+i*n;
}

以这种方式,b可以按照您的要求用作矩阵。然而,这将浪费malloc(m* sizeof(int *))来保存b。
或者您可以:
int m = 2;
int n = 4;
int *a = malloc(m*n*sizeof(int));

use a[m*i+j] as a[i][j]


0
希望下面的内容对你有帮助。我还没有测试过它,只是提供给你语法。
int** abc; // Your 2D array pointer abc[N][M]

abc = (int**)malloc(dim1_max * sizeof(int*)); // dim1_max is N
for (int i = 0; i < dim1_max; i++) {
  abc[i] = (int*)malloc(dim2_max * sizeof(int)); // dim2_max is M
}

[....your array used....]
//Once you allocate dynamically you need to free the memory. IMP point.
for (int i = 0; i < dim1_max; i++) {
  free(abc[i]);
}
free(abc);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接