将2D数组传递给C中的函数

时间:2011-02-12 23:12:48

标签: c arrays function pointers

本质上,我有一个数据矩阵(比如说int),我想存储在一个二维数组中,其中维度直到运行时才知道(比如x列和y行)。我想在函数中填充数组,所以我假设我需要做这样的事情:

int main(int argc, char **argv) {
    int y = atoi(argv[1]);
    int x = atoi(argv[2]);
    int **matrix = malloc(x * sizeof(int*));
    populateMatrix(matrix, y, x);
    return 0;
}

void populateMatrix(**matrix, int y, int x) {
    int i, j;
    for (i = 0; i < y; i++) {
        for (j = 0; j < x; j++) {
            matrix[i][j] = i * j; // populated with trivial data to keep it simple
        }
    }
}

显然这不起作用,但我不确定如何做我正在描述的内容。

4 个答案:

答案 0 :(得分:4)

你缺少的是每个内部数组都需要被malloc化。

int **matrix = malloc(x * sizeof(int *));

应该是这样的:

int **matrix = (int **)malloc(y * sizeof(int *));
for (i = 0; i < y; ++i) {
    matrix[i] = (int *)malloc(x * sizeof(int));
}

那就是说,我所知道的大多数矩阵库只会使用:

int *matrix = (int *)malloc(x * y * sizeof(int));

然后使用:

int n = matrix[y * cols + x];

阅读各个元素。对于(非稀疏)矩阵,这比为每行分别分配块更有效。它还保证数据在内存中是连续的,这可以使CPU缓存更有效。

答案 1 :(得分:0)

你能不能只使用一维数组并按行或列存储?然后,您只需使用array[row * numcols + col]而不是array[row][col]访问数组元素

内部确实没有任何区别,因为内存并不关心你是否使用两个维度或一个维度。

答案 2 :(得分:0)

main中的矩阵是指向int的指针。你的程序为x指针分配空间。考虑到populateMatrix中的循环,这应该是指向int的y指针的空间。更重要的是,您没有为行分配空间。你需要在main中使用另一个循环来分配y行,每行大到足以保持x整数。

答案 3 :(得分:0)

C99有一个简单的工具,经常不赞成,但可以提供你想要的,可变长度数组,VLA。

void populateMatrix(size_t y, size_t x, double matrix[x][y]);

他们不赞成的原因是,如果你直接使用它们在堆栈上分配矩阵,你可能会发现堆栈溢出。你可以通过实际传递指向这些野兽的指针来避免这种情况:

void populateMatrix2(size_t y, size_t x, double (*matrix)[x][y]) {
  for (... something ...) {
     (*matrix)[i][j] = 33.0;
  }
}

并且在某些功能中:

double (*myMatrix)[n][m] = malloc(sizeof(*myMatrix));
populateMatrix2(n, m, myMatrix);

对于语法,您只需要将尺寸的大小放在参数列表中的矩阵之前,以便在那时知道它们。同时使用size_t作为索引和对象大小的所有内容,通常没有意义为它们设置签名类型。