Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中将变长数组声明为全局变量_C_Global Variables_Variable Length Array - Fatal编程技术网

在C中将变长数组声明为全局变量

在C中将变长数组声明为全局变量,c,global-variables,variable-length-array,C,Global Variables,Variable Length Array,如何将可变长度数组声明为全局变量 当在扫描长度之前在函数中声明可变长度数组时,它将编译但不运行。它给出了分段错误。当同一声明语句移到扫描语句下方时,它运行正常 如果我们想要一个可变长度数组对所有函数全局可用,我们如何做到这一点?这里的问题是,只能通过某些函数扫描数组的长度。可变长度数组(即,使用运行时值调整大小的数组)不能是全局变量,因为用于大小的表达式显然必须在编译时计算。它只能在堆栈上生存。大概您得到的是一个静态数组,其大小取决于您在代码中定义它的位置(因为您正在重新定义它所依赖的内容) 为

如何将可变长度数组声明为全局变量

当在扫描长度之前在函数中声明可变长度数组时,它将编译但不运行。它给出了分段错误。当同一声明语句移到扫描语句下方时,它运行正常

如果我们想要一个可变长度数组对所有函数全局可用,我们如何做到这一点?这里的问题是,只能通过某些函数扫描数组的长度。

可变长度数组(即,使用运行时值调整大小的数组)不能是全局变量,因为用于大小的表达式显然必须在编译时计算。它只能在堆栈上生存。大概您得到的是一个静态数组,其大小取决于您在代码中定义它的位置(因为您正在重新定义它所依赖的内容)

为什么不能使用全局指针和realloc()根据需要调整其大小?

您不能这样做。 以下是标准草案的内容:

6.7.6.2数组声明器

2如果标识符被声明为具有可变修改类型,则 应为普通标识符(如6.2.3所定义),无 链接,并具有块范围或功能原型范围。如果 标识符被声明为具有静态或线程的对象 存储持续时间,它不应具有可变长度数组类型

而且

10示例4所有可变修改(VM)类型的声明必须位于块范围或 功能原型范围。使用_Thread_local、static或extern声明的数组对象 存储类说明符不能具有可变长度数组(VLA)类型。但是,使用 静态存储类说明符可以具有VM类型(即指向VLA类型的指针)。最后,所有 使用VM类型声明的标识符必须是普通标识符,因此不能是 结构或工会


在C语言中,无法将变长数组声明为全局变量,因为必须在知道其大小之前分配它,因此编译器无法知道应该为其分配多少内存。但是,您可以(也应该)做的是动态分配:

char* my_dynamic_array = NULL;

void f(unsigned int size)
{
    if(!my_dynamic_array) {
        my_dynamic_array = malloc(size);
    }
    /* do something with the array */
}

int main(void)
{
    f(1024); /* set size dynamically */
    /* do something with the array */
    free(my_dynamic_array); /* free the allocated memory */
    return 0;
}

开业7年后,哼哼回答了这个问题。与迄今为止得到的答案相反,胆大鬼们还有希望:)

我遇到了这种需求,在一个线程应用程序中共享一个全局VLA(dyn阵列等)。 简而言之,我需要我的线程共享一个全局数组,我在这里把同步/缓存问题放在一边,因为我只想展示如何共享VLA,这个例子可以衍生出其他需要(例如外部VLA等)

下面是代码,后面是解释其工作原理的注释

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

int gn, gm, *ga;                                                 /* (*2) */

void worker(int tndx, long n, long m, int a[n][m])               /* (*6) */
{ long *np=&n, *mp=&m, i=mp-np, *ap=mp+i;                        /* (*7) */

  *ap=(long)ga;
  /* At this oint the worker can elegantly access the global dyn array.
   * elegantly mean through a[i][j].
   */
  printf("worker %d started\n", tndx);
  for(int j=0;j<m;j++)                        
  { a[tndx][j]+=(tndx*1000);                                     /* (*8) */
  }
}

void *init_thread(void *v)
{ int x[1][1], tndx = (int)(long)v;                              /* (*4) */
  printf("thread #%d started\n", tndx);
  worker(tndx, (long)gn, (long)gm, x);                           /* (*5) */
  return(0);
}

int main(int ac, char **av)
{ int n=atoi(av[1]), m=atoi(av[2]);
  pthread_t tt[n];  /* thread table */                           /* (*1) */
  int a[n][m];      /* dyn array    */                           /* (*1) */

  gn=n, gm=m, ga=&a[0][0]; /* globals setup shared by workers */ /* (*2) */
  for(int i=0, k=0;i<n;i++)for(int j=0;j<m;j++)a[i][j]=k++;      /* (*3) */

  printf("Init  a[][]\n");
  for(int i=0, k=0;i<n;i++)for(int j=0;j<m;j++)
    printf("a[%d][%d]=%d\n",i,j,a[i][j]);
  for(int i=0;i<n;i++)
  { if(pthread_create(&tt[i], NULL, init_thread, (void *)(long)i))
    { exit((printf("pthread_create %d failed\n",i),1));
    }
  }
  printf("Draining threads\n");
  for(int i=0;i<n;i++)
  { pthread_join(tt[i],0);
  }
  printf("Final a[][]\n");
  for(int i=0, k=0;i<n;i++)for(int j=0;j<m;j++)
    printf("a[%d][%d]=%d\n",i,j,a[i][j]);
  pthread_exit(NULL);
}
每个线程都修改了它的行my,添加了它的ID*1000

因此,我们可以在全球范围内定义VLA

VLA很酷,不需要学习者阅读alloca()等,但是需要全局的,正如编译时所解释的,这是不可能的,GCC(libgcc?)应该能够在运行时提供一个API来“修补”VLA基addr

我现在知道很多人会反对arg addr taking,stack direction hack,等等,但这是许多其他代码的工作方式,vau args,alloca,等等。。。所以它可能看起来很丑陋,但这种丑陋是可以隐藏的

干杯,
Phi

作为全局变量的可变长度数组没有意义。可变长度数组的大小取决于长度变量的运行时值。如果你展示一些代码,那么它会有所帮助。
VY$ cc -o t2 t2.c -lpthread

VY$ ./t2 3 4
Init  a[][]
a[0][0]=0
a[0][1]=1
a[0][2]=2
a[0][3]=3
a[1][0]=4
a[1][1]=5
a[1][2]=6
a[1][3]=7
a[2][0]=8
a[2][1]=9
a[2][2]=10
a[2][3]=11
thread #0 started
worker 0 started
thread #2 started
worker 2 started
thread #1 started
worker 1 started
Draining threads
Final a[][]
a[0][0]=0
a[0][1]=1
a[0][2]=2
a[0][3]=3
a[1][0]=1004
a[1][1]=1005
a[1][2]=1006
a[1][3]=1007
a[2][0]=2008
a[2][1]=2009
a[2][2]=2010
a[2][3]=2011