【问题标题】:How to declare a variable sized 2D arrays global in C?如何在 C 中全局声明一个可变大小的二维数组?
【发布时间】:2018-03-22 16:15:51
【问题描述】:

我正在制作一个随机的 n*n 矩阵,但在程序已经运行之前我不知道 n 的值。

我能够像这样在 main() 中创建 n*n 个矩阵:

    double (*m1)[n];
    m1 = malloc(sizeof *m1 * n);

    double (*m2)[n];
    m2 = malloc(sizeof *m2 * n);

但是现在我必须在 main 之外使用这些矩阵并且需要它们是全局的,但是我完全不知道如何使它们成为全局的。我打算用多个线程阅读这两个矩阵,并且需要它们易于访问。我知道我可以制作一个结构来传递多个参数,但是我需要在全局范围内定义一个具有可变长度数组的结构,这样问题就会重新出现。感谢您的宝贵时间。

【问题讨论】:

  • 简单的标准variable-length array 怎么样?喜欢double m1[n][n];?如果其他函数需要使用矩阵,将它们作为参数传递?
  • 尝试点击这个链接,你可能会得到一些线索[stackoverflow.com/questions/7839637/…
  • @Someprogrammerdude 之后我将使用多个线程读取数组。据我所知,我无法将具有可变长度数组的结构传递给线程。因此,希望它们全球化的问题。
  • 正确的解决办法是不要用全局变量做意大利面条式编程。

标签: c arrays matrix


【解决方案1】:

正确、正确的解决方案是不使用全局变量。在线程中分配数组,该数组将在整个程序的执行过程中持续存在。

如果由于未知的原因,这不是一个选项,那么您将不得不想出一些全局存储数组大小的解决方案。您可以为此创建一个简单的 ADT,例如具有灵活数组成员形式的“错位”二维数组的结构。示例:

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

typedef struct
{
  size_t x;
  size_t y;
  double array [];
} double_array2d_t;

double_array2d_t* array2d = NULL;

int main()
{
  /* let x and y be some manner of run-time values: */
  int x = 3;
  int y = 2;

  array2d = malloc(sizeof(*array2d) + sizeof(double[x][y]));
  array2d->x = x;
  array2d->y = y;

  double count = 0.0;
  for(int i=0; i<x; i++)
  {
    for(int j=0; j<y; j++)
    {
      array2d->array[i*y + j] = count++;
      printf("%f ", array2d->array[i*y + j]);
    }
    printf("\n");
  }

  ...

  free(array2d);
}

当然,如果您从多个线程访问它,您必须像往常一样使用互斥锁来保护数据。

【讨论】:

    【解决方案2】:

    只需声明为双指针并在 main 中分配内存。更多详情请参考this

    #include <stdio.h>
    int **a;
    void fun(int n)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
                printf("%d ",a[i][j]);
        }
    }
    int main(void) 
    {
        int n;
        scanf("%d",&n);
        a = (int **)malloc(n * sizeof(int *));
        for(int i=0;i<5;i++)
        {
            a[i]=(int*)malloc(n*sizeof(int));
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        fun(n);
        return 0;
    }
    

    工作代码:https://ideone.com/OMQ4qA

    【讨论】:

    • 这太棒了!最后一个问题,我将如何正确释放分配的内存?在这种情况下,只需免费(a)?
    • 没有。你不能那样做。参考stackoverflow.com/questions/11015360/free-a-double-pointer"
    • 这不是一个二维数组,而是一个基于指针的查找表。缓存访问会很慢,这会不必要地导致堆碎片。除非 OP 需要单独更改“数组”维度,否则绝对没有理由使用此代码。当您可以快速访问时,为什么还要慢速访问?见Correctly allocating multi-dimensional arrays。 (当然,当您使用全局变量进行意大利面条式编程时,VLA 也不是一种选择。)
    • 我几乎不怀疑什么是 OP(我猜是输出)和 VLA? (我正在努力学习新事物)
    • @Sridharan OP = 原始海报的互联网俚语,提出问题的人。 VLA 是可变长度数组的 C 编程术语。
    猜你喜欢
    • 1970-01-01
    • 2012-03-12
    • 2012-12-11
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多