【问题标题】:Declare dynamically sized array in global scope在全局范围内声明动态大小的数组
【发布时间】:2019-12-03 17:31:01
【问题描述】:

不经常使用 C,我遇到了一个可能很简单的问题。我有几个函数,需要访问全局数组变量g。但是这个变量的实际大小必须在init()-函数中定义。大小取决于其他一些东西,所以 g 必须以某种方式声明为动态大小。我阅读了malloc 和其他功能,但我不确定如何正确使用它们。

例子:

double g[dynamic]; // size is not known yet
int n;

void init()
{
   // calculate "n" for array size
   n = ...
   // declare and initialze g with a size "n"
}

void dostuff()
{
   for (int i = 0; i < n; i++)
      work(g[i]);
}

我应该如何解决这个问题?

【问题讨论】:

    标签: c dynamic malloc size


    【解决方案1】:

    您不能使用数组。您必须使用指针

    double *global_array; // size is not known yet
    size_t nglobal_array; // may be helpful to have the size
    
    void init(void)
    {
       // calculate "nglobal_array" for array size
       nglobal_array = 42;
       // declare and initialze global_array with a size "nglobal_array"
       global_array = malloc(nglobal_array * sizeof *global_array);
       if (global_array == NULL) {
           fprintf(stderr, "Error allocating resources.\nProgram aborted.\n");
           exit(EXIT_FAILURE);
       }
    }
    
    void dostuff()
    {
       for (int i = 0; i < nglobal_array; i++)
          work(global_array[i]);
    }
    

    当您不再需要它时,别忘了free(global_array)

    完整的用法会是这样的

    #include <stdlib.h>
    // includes
    // declarations & definitions as above
    int main(void) {
        init();
        dostuff();
        free(global_array);
    }
    

    【讨论】:

      【解决方案2】:

      你想要达到的目标在 C 中是不可能的。

      全局数组在编译时或至少在链接时必须具有固定大小。

      你可以声明没有指定大小的数组:

      extern double g[];
      

      但是它必须在某个地方定义一个实际大小,根据定义位置的常量表达式计算,并且大小不能从上面的声明中确定,所以它必须以其他方式传递给将使用数组:或者隐式地使用一个特殊的值来表示数组的结尾(例如'\0' 用于char 字符串),或者通过您发布的单独变量显式地使用。但是请注意,ng 是非常糟糕的全局变量名称选择,因为它们很可能与局部变量名称发生冲突并且对读者没有任何意义。

      如果直到运行时才知道大小,您应该定义一个指针而不是一个数组,并定义一个单独的变量,该变量具有将由初始化函数分配的数组长度。

      double *g;
      size_t g_length;
      

      【讨论】:

      • 我觉得他只是很困惑,认为“declare”的意思是“make”。
      【解决方案3】:

      没有。 C不这样做。在全局范围内声明的数组在二进制文件中为它们分配了固定空间(Windows 上的 .EXE 文件和 Linux 上的 ELF 可执行文件)。如果你想要一个动态大小的数组,你需要动态分配它。 示例在这里:

      #include <stdlib.h>
      #define ARRAY_SIZE 100
      typedef char T; //your type here
      T* array;
      
      void init() {
          array = malloc(sizeof(T) * ARRAY_SIZE); //array filled with garbage values
          //array = calloc(ARRAY_SIZE, sizeof(T)); //array filled with 0x00
      }
      void finish() {
          free(array); // DO NOT ACCESS ARRAY AFTER THIS CALL!
      }
      int main() {
          init();
          array[6] = 63; //access array as normal
          finish();
          //array[41] = 23; //will most likely crash due to a segmentation fault, also called an access violation on Windoez
      }
      

      【讨论】:

      • 该代码有点毫无意义,ARRAY_SIZE 是不变的。在这里你可以写T array[ARRAY_SIZE];
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多