【问题标题】:allocate matrix in C在 C 中分配矩阵
【发布时间】:2011-01-08 21:08:41
【问题描述】:

我想分配一个矩阵。

这是唯一的选择吗:

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

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

【问题讨论】:

标签: c pointers matrix malloc


【解决方案1】:

嗯,你没有给我们一个完整的实现。我猜你的意思是。

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 中处理矩阵的首选方式。这是因为现在矩阵将连续存储在内存中,您可以从 locality of reference 中受益。基本上,CPU缓存对你来说会更快乐。

【讨论】:

  • 如果你的编译器支持变长数组或者cols是一个编译时常量,你甚至不需要自己计算偏移量;如果您使用int (*mat)[cols] = malloc(rows * sizeof *mat),您可以通过mat[i][j] 访问元素并且仍然使用连续的内存块
  • 即使忽略性能,单个分配也更可取,因为它更简单。以后要释放的东西更少,不需要处理部分分配失败。
  • 如果每个 malloc 都创建了不连续的内存块,使它们的地址不连续,这不是问题吗?例如,第一个 malloc 可能返回指针 0x635,而其他 malloc 可能返回指针 0xA279、0xB7DD 等。如果发生这种情况,上述简单的计算将无法正常工作。
【解决方案2】:

其他答案已经涵盖了这些,但为了完整起见,comp.lang.c FAQ 有一个相关条目:

How can I dynamically allocate a multidimensional array?

【讨论】:

【解决方案3】:

你能做的是

int (*mat)[col];
mat=(int (*)[col])malloc(sizeof(*mat)*row);

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      怎么样:

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

      【讨论】:

        【解决方案6】:

        可以将其折叠为对 malloc 的一次调用,但如果您想使用 2d 数组样式,您仍然需要 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:好点,这也很容易解决,但就像我在回答中指出的那样,这是未经测试的。现在解决了这个问题。
        猜你喜欢
        • 2013-04-06
        • 2023-03-03
        • 2013-05-21
        • 2014-07-06
        • 2018-07-08
        • 2021-02-20
        • 1970-01-01
        相关资源
        最近更新 更多