【问题标题】:How to declare and initialize this array of structs in C when the length is not known till runtime?当直到运行时才知道长度时,如何在 C 中声明和初始化这个结构数组?
【发布时间】:2010-12-02 19:23:18
【问题描述】:

foo.c

#include "main.h"
unsigned char currentBar;
struct foo myFoo[getNumBars()];

void initMyFoo(void)
{
 currentBar=(getNumBars()-1);
 for(i=0; i<(sizeof(myFoo)/sizeof(myFoo[0])); i++)
 {
  myFoo[i].we = 1;
  myFoo[i].want = 0;
  myFoo[i].your = 0;
  myFoo[i].soul = 0;
 }
}

main.c

#include "foo.h"
unsigned char getNumBars()
{
 return getDipSwitchValues();
}
initMyFoo();

(struct foo 在 foo.h 中声明)

此代码必须在没有硬编码 Bars 数字的情况下执行,因为 Bars 的数量会根据用户设置的 DIP 开关而改变。现在我无法初始化 myFoo;我收到错误“初始化程序中预期的常量表达式”。我是否必须像这样初始化它:

struct foo myFoo[];

稍后再更改?如果是这样,我如何使 myFoo[] 长度正确?我显然没有与所需大小相对应的常量。我需要动态分配这个吗?

我找到了这个类似的答案,但对我没有太大帮助 - C++ a class with an array of structs, without knowing how large an array I need

【问题讨论】:

    标签: c struct compilation


    【解决方案1】:
    struct foo* myFoo;
    unsigned int myFooSize;
    
    void initMyFoo(void)
    {
      myFooSize = getNumBars();
      myFoo = malloc(myFooSize * sizeof(*myFoo));
      for (i=0; i<myFooSize; i++) {
        /* ... */
      }
    }
    
    void cleanupMyFoo(void)
    {
      free(myFoo);
      myFoo = NULL;
      myFooSize = 0;
    }
    

    【讨论】:

    • 如果他使用 C,他不需要显式地将指针从 malloc 转换回来。
    • 如果getNumBars() 是不受信任的用户输入,您应该测试乘以sizeof *myFoo 的结果是否回绕。
    【解决方案2】:

    1 - 在 C99 中,您可以使用 variable length arrays,它允许您创建长度由运行时确定的数组。您也可以通过编译器扩展来使用它们(GCC 支持它们用于非 C99 C 和 C++),但这不是一个可移植的解决方案。

    int someUnknownSize = 0;
    
    /* some code that changes someUnknownSize */
    
    struct foo myFoo[someUnknownSize];
    

    2 - 使用malloccalloc 声明将在运行时分配内存的指针。

    struct foo *fooPtr = 0; /* null pointer to struct foo */
    int sizeToAlloc = 0;
    /* determine how much to allocate/modify sizeToAlloc */
    fooPtr = malloc(sizeToAlloc * sizeof(*fooPtr));
    
    /* do stuff with the pointer - you can treat it like you would an array using [] notation */
    free(fooPtr);
    

    【讨论】:

      【解决方案3】:

      我通常会选择预期的最大数组大小,如果需要,只需调整它的大小:

      type * a = calloc(sizeof(type),exp_array_size);
      

      在将新值推送到数组时(是的,好的,我将其视为堆栈......),我检查其当前大小与新值:

      if (current_size > max_size) {
          max_size *= 2;
          realloc(a,max_size*sizeof(type));
      }
      

      【讨论】:

        猜你喜欢
        • 2010-09-30
        • 2017-03-26
        • 2018-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 2011-02-08
        相关资源
        最近更新 更多