在C中存储2d数组的数组

时间:2014-12-07 21:08:36

标签: c arrays matrix malloc

我试图将一系列矩阵存储在连续的内存块中,然后检索它们。每个数组的大小都相同(n x n)。

据我了解,我需要做的是:

  1. 分配并初始化我需要存储/检索的每个数组。

  2. 分配一个大小为(# arrays) * sizeof (1 array)的连续内存块,并将一个指针***matrices分配给块的开头

  3. 将每个数组复制到matrices[0]matrices[1],...

  4. 的块中
  5. matrices[0]matrices[1],...发送至matrix_print函数

  6. 进行打印

    现在,显然我误解了一些东西,因为它不起作用。这是我在崩溃之前得到的输出:

    Matrix A is 16 bytes.
    Matrix B is 16 bytes.
    So, we will allocate 32 bytes in row_blocks.
    Matrix A:
    | 1  1 |
    | 2  2 |
    Matrix B:
    | 2  2 |
    |
    

    以下是我试图开始工作的测试用例的代码:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    void matrix_print(int dim, int ***matrix);
    void matrix_init(int dim, int matrix[dim][dim], int val);
    
    int main(int argc, char *argv[])
    {
        int dim = 2;
    
        int A[dim][dim], B[dim][dim];
    
        matrix_init(dim, A, 1);
        matrix_init(dim, B, 2);
    
        printf("Matrix A is %d bytes.\n", sizeof A);
        printf("Matrix B is %d bytes.\n", sizeof B);
    
        int ***matrices = malloc(sizeof A + sizeof B);
    
        printf("So, we will allocate %d bytes in matrices.\n\n",
                sizeof A + sizeof B);
    
        memcpy(matrices[0], A, sizeof (A));
        memcpy(matrices[1], B, sizeof (B));
    
        printf("Matrix A:\n");
        matrix_print(dim, &matrices[0]);
        printf("Matrix B:\n");
        matrix_print(dim, &matrices[1]);
    
        return 0;
    }
    
    void matrix_print(int dim, int ***matrix)
    {
        for (int i = 0; i < dim; i++) {
            printf("|");
            for (int j = 0; j < dim; j++) {
                printf("%2d ", matrix[i][j]);
            }
            printf("|\n");
         }
    }
    
    void matrix_init(int dim, int matrix[dim][dim], int val)
    {
        for (int i = 0; i < dim; i++) {
            for (int j = 0; j < dim; j++) {
                matrix[i][j] = val;
            }
         }
    }
    

1 个答案:

答案 0 :(得分:3)

C中二维矩阵的快乐!

当您将一维数组int[dim]传递给函数时,它会衰减为指向其第一个元素int *int[]的指针,从而丢失其大小的信息。过程

二维数组int[dim][dim]不会衰减成双指针int **,而是指向指向整数dim整数行的第一个元素的指针,{{ 1}}或int (*)[dim]。也就是说,因为特殊处理了恒定行大小的多维数组;它们被实现为连续的数据块,其中常量大小用于计算索引。 (此处的常量表示所有行和整个矩阵运算的常量;在您的情况下,此值可以是C99中的变量。)

int[][dim]类型的矩阵无法表示为int[dim][dim],因此您应该调整矩阵数组的类型:

int **

打印功能的签名也会改变:

int (*matrices)[dim][dim];

matrices = malloc(sizeof A + sizeof B);

你这样称呼它:

void matrix_print(int dim, int matrix[dim][dim])
{
    for (int i = 0; i < dim; i++) {
        printf("|");
        for (int j = 0; j < dim; j++) {
            printf("%2d ", matrix[i][j]);
        }
        printf("|\n");
     }
}

没有地址操作符matrix_print(dim, matrices[0]);

脚注:

  • &是指向长度为int (*x)[dim]的整数数组的指针。 dim是指向int *x[dim]的指针长度为dim的数组。

  • 我认为特殊处理是Fortran如何存储多维数组的。另一方面,如果您已经分配了一组指针,则它们是int。这样的数据结构可以容纳不规则的矩阵。

  • 矩阵是具有可变长度(VLA)的C99样式数组,无法初始化,因此int **必须是单独的声明和赋值。