本质上,我有一个数据矩阵(比如说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
}
}
}
显然这不起作用,但我不确定如何做我正在描述的内容。
答案 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
作为索引和对象大小的所有内容,通常没有意义为它们设置签名类型。