从 C 中的动态值创建和循环二维数组

Creating and looping a two-dimensional array from dynamic values in C

我正在尝试基于两个预先计算的值创建一个二维数组(此处 len1 和 len2 是常量,但它们来自另一个函数)。当我 运行 这个时,我得到了分段错误。我对 C 很陌生,这是我的第一个任务。无法从指南或 SO 中弄清楚,周围有人可以帮助我吗?

我想二维数组的动态创建是错误的。但是找不到一个好的例子..

int main() {
    
    int y, x;
    
    int my_val = 10; // dynamnic value calculated by another func
    int len1 = 3; // dynamnic value calculated by another func
    int len2 = 3; // dynamnic value calculated by another func
    
    int cols = len1 + 1;
    int rows = len2 + 1;
    
    int **twodarr = (int **)malloc(rows * cols * sizeof(int));
    
    for (x = 1; x < cols; x++) {
        for (y = 1; y < rows; y++) {
            twodarr[y][x] = my_val;
        }
    }
    
    return 0;
}

你必须分配每个rows

// allocation of cols
int **twodarr = (int **)malloc(cols * sizeof(int*));// note it is sizeof(int*)

// allocation each rows (in each cols)
for (x = 0; x < cols; x++) {
    twodarr[x] = (int *)malloc(rows * sizeof(int));
}

问题是int **twodarr不能用于二维数组,它与它们没有任何关系。您需要将其交换为指向二维数组的指针。或者更方便的是,指向一维数组的指针 - 在这种情况下指向行的指针,假设 [rows][cols].

此外,C 中的数组从索引 0 开始。

包含错误修复和简单打印示例的代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    
    int my_val = 10; // dynamnic value calculated by another func
    int len1 = 3; // dynamnic value calculated by another func
    int len2 = 3; // dynamnic value calculated by another func
    
    int rows = len2 + 1;
    int cols = len1 + 1;
    
    int (*twodarr)[cols] = malloc( sizeof(int[rows][cols]) );
    
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            twodarr[r][c] = my_val;
            printf("%d ", twodarr[r][c]);
        }
        puts("");
    }
    
    free(twodarr);
    
    return 0;
}

数组从来不是C中的第class个元素,多维的支持更差。最初,只有 C 使用常量大小的数组,因为指针运算对于动态一维数组来说已经足够了,而指针是该语言的基本元素。

C99 引入了 使用的可变长度数组的概念。不幸的是,C11 将它们定义为可选功能,Microsoft 选择不支持它们以与 C++ 兼容。

如果您使用 Microsoft 编译器或希望与不支持可选 VLA 功能的环境兼容,您将不得不使用旧的 linear 习惯用法:您只使用一维数组并使用复合索引计算:元素(i,j)的索引是j + i * cols,其中cols是第二维的大小。

您的代码可能会变成:

...
int *twodarr = malloc(rows * cols * sizeof(int)); // BEWARE: actualy 1D array!

for (x = 1; x < cols; x++) {
    for (y = 1; y < rows; y++) {
        twodarr[x + y*cols] = my_val;
    }
}
...

@kcabus 做对了......并且不可否认,为了理智起见,这种方式更具可读性。

另一种方法是将其声明为内存块,但它更令人困惑。

比如

int *twodarr = (int*)calloc((rows * 
cols), sizeof(int));
// accessed as follows
*(twodarr + rows*r + c) = value;
// rows * position + position 2
// much more confusing.

第三种选择是创建一个类似 POINT 的结构(或仅使用点),并通过仅创建一个 POINT 数组来使用两个值,例如。但我假设你不想在一个循环中处理这个......我不怪你嘿。