在C中分配矩阵

19

我想分配一个矩阵。

这是唯一的选项吗:

int** mat = (int**)malloc(rows * sizeof(int*))

for (int index=0;index<row;++index)
{
    mat[index] = (int*)malloc(col * sizeof(int));
}

2
不要在C中强制转换malloc的结果 - phuclv
6个回答

51

好的,你没有给我们一个完整的实现。我认为你是这个意思。

int **mat = (int **)malloc(rows * sizeof(int*));
for(int i = 0; i < rows; i++) mat[i] = (int *)malloc(cols * sizeof(int));

这里有另一个选项:

int *mat = (int *)malloc(rows * cols * sizeof(int));

然后,您可以使用模拟矩阵

int offset = i * cols + j;
// now mat[offset] corresponds to m(i, j)

对于行主序和

int offset = i + rows * j;
// not mat[offset] corresponds to m(i, j)

对于列优先顺序。

在C语言中处理矩阵的首选方式是这两种选项之一。这是因为现在矩阵将被连续地存储在内存中,您可以从引用局部性中受益。基本上,CPU缓存会更加高兴。


2
如果您的编译器支持可变长度数组或者cols是一个编译时常量,您甚至不需要自己计算偏移量;如果您使用int (*mat)[cols] = malloc(rows * sizeof *mat),您可以通过mat[i][j]访问元素,并且仍然使用一个连续的内存块。 - Christoph
3
即使不考虑性能,单次分配也更可取,因为它更简单。需要处理的清理工作较少,也无需处理部分分配失败的情况。 - jamesdlin
1
如果每个malloc创建的内存块是不连续的,使它们的地址不是连续的,那么这不会成为一个问题吗?例如,第一个malloc可能返回指针0x635,而其他的malloc可能返回指针0xA279、0xB7DD等。如果发生这种情况,像上面所述的简单计算就行不通了。 - Bruno Philipe

7

http://c-faq.com 是一个非常出色的资源,提供了许多 C 语言技巧(对于 C++ 可以参考 http://www.parashift.com/c++-faq/)。 - 42n4

5
你可以做的是
int (*mat)[col];
mat=(int (*)[col])malloc(sizeof(*mat)*row);

然后将这个新矩阵用作 mat[i][j]


3

您也可以使用calloc,它会为您额外初始化矩阵的零值。签名略有不同:

int *mat = (int *)calloc(rows * cols, sizeof(int));

2
只需要这样怎么样:
int* mat = malloc(rows * columns * sizeof(int));

0

你可以将它折叠成一次malloc调用,但如果你想使用二维数组风格,仍然需要for循环。

int** matrix = (int*)malloc(rows * cols * sizeof(int) + rows * sizeof(int*));

for (int i = 0; i < rows; i++) {
    matrix[i] = matrix + rows * sizeof(int*) + rows * cols * sizeof(int) * i;
}

虽然未经测试,但你可以理解这个想法。否则,我会遵循Jason的建议。


只有当 sizeof(int) == sizeof(int*) 时,此代码才能正常工作 - 否则,偏移量将是错误的;即使这种情况下也可能出现错误。 - Christoph
@Christoph:说得好,这也很容易解决,但正如我在答案中指出的那样,这是未经测试的。现在已经修复了这个问题。 - Matthew Scharley

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