在C中初始化具有可变长度数组的结构

时间:2016-07-22 09:43:05

标签: c struct variable-length-array

有没有人知道是否有办法初始化包含可变长度数组的结构而不首先在单独的变量中初始化数组(并且不使用malloc)?

我的结构如下:

struct my_struct {
    int *values;
    int size;
}

现在在我的代码中我有:

void my_function (int size) {
    int values[size];
    struct my_struct mystr = {
        .values = values,
        .size = size
    };
    ...
}

(首先初始化数组,然后是结构。这是有效的,但为数组声明一个单独的变量看起来很尴尬。)

这可能会有效:

void my_function (int size) {
    struct my_struct mystr = { 
        .values = calloc (size, sizeof (int)),
        .size = size
    };
    ...
}

(但我不想使用mallocs)

但我想写的是:

void my_function (int size) {
    struct my_struct mystr = { 
        .values = (int[size]){},
        .size = size
    };
    ...
}

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

首先,请注意,如果要返回结构,则无法使用堆栈中的数组。

int values[size];
struct my_struct mystr = {
    .values = values,
    .size = size
};
return mystr;

这是行不通的,因为values的生命周期在您返回时结束。如果您尝试将mystr存储在函数参数指向的值中,则同样适用。

显然你没有这样做,但我认为无论如何都值得一提。

回答你的问题:这取决于具体情况。

您能确定size很小吗?否则你的堆栈将在int values[size]中溢出。它是小而可预测的吗?坚持你的第一个解决方案。如果它可能很大或依赖于用户输入,请务必使用malloc

您是否以某种方式返回或保留指向您的结构或值的持久指针?使用malloc(请参阅我的第一句话)。

或者,您也可以使用struct hack,但无论如何都必须malloc {/ 1}}。

还有一件事,你写道:

  

(首先初始化数组,然后是结构。这是有效的,但是   为数组声明一个单独的变量看起来很尴尬。)

我不确定你的意思,但mystr仅为int *,无论数组的大小如何。所以你没有为1个阵列分配两倍的内存,如果这就是你的想法。

答案 1 :(得分:-1)

初始化程序是由初始化程序列表初始化的未命名对象。在函数体外,对象具有静态存储持续时间。因此可以使用这种对象的地址。在可变参数宏的帮助下,您可以尝试→

 #include <stdio.h>

 struct test {
   int count;
   int *values;
 } test[] = {
 #define init(...) { .count=sizeof( (int[]) {__VA_ARGS__} )/sizeof(int), .values=(int *)&(int []){__VA_ARGS__} }
              init(0,1,2,3,4),
              init(2,4,6,8),
              init(1,3),
              init(42)
            };
 #define test_size ((int) (sizeof test/sizeof *test))

 int main(void)
 {
   for(int array=0; array<test_size; ++array) {
     printf("array %d (%d) : [ ", array+1, test[array].count);
     for(int i=0; i<test[array].count; ++i)
       printf("%d ", test[array].values[i]);
     puts("]");
   }
   return 0;
 }