如何初始化尺寸由argc和argv确定的2D数组?

时间:2019-03-14 21:37:39

标签: c dynamic-memory-allocation

我正在研究代码,该代码将跟踪每次访问数组中的特定元素的时间。数组本身将根据用户的输入动态分配,因此,我所寻找的功能都不是我想要的。更具体地说,如何动态分配数组的行和列,然后将每个元素初始化为0? 例如
./SIM A B

int* array_columns = malloc(atoi(argv[1]) * sizeof(int));
int* array_rows = malloc(atoi(argv[2]) * sizeof(int)); 
int array[*array_rows][*array_columns];

我所见过的一切都需要事先知道每一行/每一列中的元素数量。谁能提供有关如何将此数组初始化为0的任何指针?编辑:我在尝试建立阵列的行中添加了

2 个答案:

答案 0 :(得分:2)

1D,2D或ND无关紧要。您可以使用两种策略:

第一个方法是创建一个简单的一维数组

int *a = (int *)malloc(atoi(argv[1]) * atoi(argv[2]) * sizeof(int));

第二个是创建一个数组数组,如下所示:

int len = atoi(argv[1]);
int len2 = atoi(argv[2]);
int **a = (int **)malloc(len * sizeof(int *));

for (int i = 0; i < len; ++i) {
    a[i] = (int *)malloc(len2 * sizeof(int));
}

第一个变体为您提供了一种初始化和删除数组的简单方法,第二个变体可以创建更大的数组,因为在这种情况下,可以将子数组的内存块保留在内存的不同位置。

要使用某个值对其进行初始化,请使用memset

用于一维阵列

memset(a, 0, sizeof(int) * len * len2);

对于数组数组

for (int i = 0; i < len; ++i) {
    memset(a[i], 0, sizeof(int) * len2);
}

PS 。一些现代的编译器允许您将动态数组初始化为静态数组,但是当您尝试在其他环境中进行编译时,该代码可能会遇到麻烦。
P.P.S。对不起,我的英文,希望有人能将其修复为易于理解的英文。

答案 1 :(得分:2)

该程序使用命令行参数分配内存,并创建可以使用数组语法访问的变量。它使用calloc将值初始化为零:

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


int main(int argc, char *argv[])
{
    int **array;

    int length = atoi(argv[1]);
    int width = atoi(argv[2]);

    array = calloc(length, sizeof(int *));
    for (int i = 0; i < length; i++) {
        array[i] = calloc(width, sizeof(int));
    }

    for (int i = 0; i < length; i++) {
        for (int j = 0; j < width; j++) {
            printf("array[%d][%d] = %d\n", i, j, array[i][j]);
        }
    }

    for (int i = 0; i < length; i++) {
        free(array[i]);
    }
    free(array);

    return 0;
}

已编译

gcc -Wall -Werror -o scratch scratch.c

输出

[user@machine]: ./scratch 3 5
array[0][0] = 0
array[0][1] = 0
array[0][2] = 0
array[0][3] = 0
array[0][4] = 0
array[1][0] = 0
array[1][1] = 0
array[1][2] = 0
array[1][3] = 0
array[1][4] = 0
array[2][0] = 0
array[2][1] = 0
array[2][2] = 0
array[2][3] = 0
array[2][4] = 0

注意

我省略了输入验证和错误检查,以使示例不多。

编译器选项

我使用-Wall -Werror打开所有警告并将其视为错误。这意味着除非所有警告原因都已解决,否则编译器将不会生成可执行文件。 -o scratch告诉编译器如何命名输出文件。