为二维数组分配空间,在C中的一个函数中



我正在用C语言解决一些计算物理问题,我对我的代码感到困惑。我花了几个星期的时间阅读有关C语言的书籍,但我对这门语言还是个新手。

我需要处理一个二维数组。每行的长度可能不同,因此,例如,我可能想使用:创建并修改一个"三角形"矩阵:[[0,1,2][1,2][2]] .

为了以一种易于维护、易于阅读和修改的方式构建我的代码,我想将部分逻辑移动到函数中。然而,它似乎比我想象的要困难。

我开始使用一种方法,我创建一个int **matrix变量并将其传递给一个函数,用一个&号为前缀并接受一个三星int: int ***,并使用矩阵作为*matrix[i][j]。我不能让它工作,然而matrix[0][i][j]工作和我只是不能得到我的头围绕它。这两个概念不是一样的吗?

下面是我的代码:
void alloc_subscript_notation(int number_of_rows, int *** matrix) {
    matrix[0] = malloc(number_of_rows * sizeof(int *));
    for (int i = 0; i < number_of_rows; i++)
        matrix[0][i] = calloc((number_of_rows-i), sizeof(int));
}
void modify_subscript(int number_of_rows, int *** matrix) {
    matrix[0][0][1] = 8;  // just set a value of an element to 8, as a proof of concept
}
void subscript_notation (int number_of_rows, int *** matrix) {
    alloc_subscript_notation(number_of_rows, matrix);
    modify_subscript(number_of_rows, matrix);  // I can even modify it
}

void alloc_star_notation(int number_of_rows, int *** matrix) {
    *matrix = malloc(number_of_rows * sizeof(int *));
    for (int i = 0; i < number_of_rows; i++)
        *matrix[i] = calloc((number_of_rows-i), sizeof(int));
    printf("alloc_subscript_notation: zeros: %d, %d, %dn",  // just a few examples
           *matrix[0][2], *matrix[1][1], *matrix[2][0]);
}
void star_notation (int number_of_rows, int *** matrix) {
    // SEGMENTATION FAULT!!!
    alloc_star_notation(number_of_rows, matrix);
}
int main (void) {
    int ** matrix;
    int number_of_rows = 3;  // it's dynamic in my program, but I use it this hard-coded value for clarity
    // I want to be able to access matrix elements here
    // All good here.
    subscript_notation(number_of_rows, &matrix);
    printf("subscript_notation ready. main: "
           " %d, %d, %d, modified: %dn",
           matrix[0][2], matrix[1][1], matrix[2][0], matrix[0][1]);
    // Segmentation Fault
    star_notation(number_of_rows, &matrix);
}

不,*matrix[i][j]matrix[0][i][j]不一样。

前者与*(matrix[i][j])相同,后者与(*matrix)[i][j]相同。

由于您试图访问使用地址操作符传递给函数的指针,因此必须使用后一种版本

我不能让它工作,然而矩阵[0][I][j]工作,我只是不能得到我的头在它周围。这两个概念不是一样的吗?

不,*matrix[i][j]matrix[0][i][j]是不同的。

给定int *** matrix,则matrix[i][j]是指向int的指针,而*matrix[i][j]实际上是matrix[i][j][0]

只是为了扩展@artm的答案,您不是(严格地说)为2D数组保留空间,在C中为2D数组保留空间(不分段)的正确方法是使用VLA:

#include <stdio.h>
#include <stdlib.h>
static void func(size_t dim, int (**matrix)[dim])
{
    *matrix = malloc(sizeof(int[dim]) * dim);
}
int main(void)
{
    size_t dim = 3;
    int (*matrix)[dim]; /* A pointer to an array of n elements */
    func(dim, &matrix);
    free(matrix);
    return 0;
}

我建议你使用一个连续的内存块来简化代码。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
void alloc_subscript_notation(int number_of_rows, int number_of_cols, int **matrix)
{
    *matrix = malloc(number_of_rows * number_of_rows * sizeof(int));
    if (*matrix != NULL)
    {
       for (int i=0; i<number_of_rows; i++)
       {
           for (int j=0; j<number_of_cols; j++)
           {
              (*matrix)[(i*number_of_cols)+j] = (i*number_of_cols)+j;
           }
       }
    }
}

int main (void) {
    int *matrix;
    int number_of_rows = 3;  // it's dynamic in my program, but I use it this hard-coded value for clarity
    int number_of_cols = 3;  // it's dynamic in my program, but I use it this hard-coded value for clarity
    // I want to be able to access matrix elements here
    // All good here.
    alloc_subscript_notation(number_of_rows, number_of_cols, &matrix);
    if (matrix != NULL)
    {
       printf("subscript_notation ready. main: "
              " %d, %d, %d, modified: %dn",
              matrix[(0*number_of_cols)+2], matrix[(1*number_of_cols)+1], matrix[(2*number_of_cols)+0], matrix[(0*number_of_cols)+1]);
    }
}

最新更新