【问题标题】:How to create at runtime a two dimensional array in C如何在运行时在 C 中创建二维数组
【发布时间】:2011-09-17 17:39:55
【问题描述】:

我无法从 2 个变量创建 2D 数组(例如 int arr[i][j] 不允许),那么如何创建动态大小的 2D 数组?

数组的维度只有在我的程序运行时才知道。该数组用于表示一个网格。我将如何在 C 中编写代码?

【问题讨论】:

  • C99 允许您声明 VLA - 可变长度数组 - 因此,如果您有 C99 编译器并且对您的工作没有人为(家庭作业)限制,您可以精确地编写 int arr[i][j];。 (如果您没有 C99 编译器,那么该买一个了。)话虽如此,您打算如何访问该数组?您可以希望使用arr[i][j] 来访问一个元素,或者您可以准备使用像arr[i*n+j] 这样的计算来访问它。这两种情况所需的内存分配模式完全不同。

标签: c multidimensional-array


【解决方案1】:

首先分配一个指针数组。

/* size_x is the width of the array */
int **array = (int**)calloc(size_x, sizeof(int*));

然后分配每一列。

for(int i = 0; i < size_x; i++) 
{
    /* size_y is the height */
    array[i] = (int*)calloc(size_y, sizeof(int));
}

您可以使用array[i][j] 访问元素。以“相反”的顺序释放内存:

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

【讨论】:

  • 我在 VS2010 中遇到了一个错误,它说它不能将 void* 转换为 int*。所以我不得不用(int**) 明确地转换为int**。这样第一行就变成了int **array = (int**)calloc(size_x, sizeof(int*));,第二行变成了(int*)
  • @JaBe 您必须在 C++ 中显式转换。但是,你为什么在 C++ 中使用 calloc?
  • 我正在使用 C++ 并调用了很多我无法更改的 C 代码。用 C++ vec 调用它看起来也好不了多少:stackoverflow.com/questions/6701816/…
  • 该 for 循环的限制应该是 size_x 而不是 size_y?
【解决方案2】:

你必须分配一个一维数组:

int* array = calloc(m*n, sizof(int));

然后像这样访问它:

array[i*n + j]

编译器在访问二维数组时正是这样做的,并且在编译时可以猜到n时可能会输出相同的代码。

【讨论】:

    【解决方案3】:

    这是一个关于 comp.lang.c 的常见问题解答(我冒昧地添加了 c-faq 标签),它甚至还有一个 FGA(经常给出答案 :-) 参见http://c-faq.com/aryptr/index.html,6.16 如何动态分配多维数组?

    【讨论】:

      【解决方案4】:

      在 C 中,多维数组只是一个数组,其中每个元素都是另一个数组。

      因此,您需要首先为一个数组(行)分配内存。您可以使用malloc() 函数,该函数将返回指向数组的指针。

      然后您遍历数组并为每个元素分配内存以用于列数。

      注意:不要忘记释放您使用 free() 函数手动分配的内存,就像使用 malloc() 分配它一样。

      【讨论】:

        【解决方案5】:

        一些示例显示了数组的多个(超过 2 个)分配;对一个 n × m 数组只进行两次分配(省略错误检查)是完全可行的:

        int **array = calloc(m, sizeof(*array));
        int *data   = calloc(m * n, sizof(*data));
        
        for (int i = 0; i < m; i++)
            array[i] = &data[i * n];
        
        
        ...use array[i][j]...
        
        free(array[0]);
        free(array);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-09
          • 2013-03-18
          • 2019-09-25
          • 1970-01-01
          相关资源
          最近更新 更多