Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

Does anyone know if there is a way to initialize a structure containing a variable length array without initializing the array first in a separate variable (and without using malloc)?

My structure looks like this:

struct my_struct {
    int *values;
    int size;
}

For now in my code I have that:

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

(Array is initialized first, then the structure. This is working but it looks awkward to declare a separate variable for the array.)

This would probably work as well:

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

(but I do not want to use mallocs)

But what I would like to write is something like:

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

Any idea?

share|improve this question
1  
Do you want to have an array without allocating space for it? – GMichael Jul 22 at 9:50
    
I know I have to allocate space for the array, but I would like to do so without using an intermediate variable such as int values[size];. – FClad Jul 22 at 10:03
    
What is wrong with ` .values = calloc (size, sizeof (int)),`? – GMichael Jul 22 at 10:05
    
Dynamic memory allocation is slower and, if you are not careful, can lead to memory leaks. Hence I try to avoid this unless it is absolutely necessary. – FClad Jul 22 at 10:18
    
So initialize the .values with NULL and put the real value when you allocate the memory – GMichael Jul 22 at 10:21

First of all, note that you cannot use an array from your stack if you want to return your structure.

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

This is not going to work since the lifetime of values ends when you return. The same applies if you try to store mystr in a value pointed by a parameter of your function.

Obviously you're not doing that, however I think it's worth to mention anyway.


Answer to your question: it depends on the situation.

Can you be sure that size is small? Or else your stack is going to overflow in int values[size]. Is it small and predictable? Stick with your first solution. If it can be large or dependent on user-input, definitely use malloc.

Are you in some way returning or retaining a persistent pointer to your structure or values? Use malloc (see my first remark).

Alternatively, you can also use the struct hack but then you would have to malloc the entire mystr anyway.


One more thing, you wrote:

(Array is initialized first, then the structure. This is working but it looks awkward to declare a separate variable for the array.)

I'm not sure what you mean, but the int * is only sizeof(intptr_t), irregardless of the size of the array. So you're not allocating twice the memory for 1 array, if that's what you're thinking.

share|improve this answer
1  
sizeof (int *) is not necessarily equal to sizeof (intptr_t). I think you missed the point; OP isn't concerned about performance or memory use in this question. He/she wants to be more expressive... Those two concepts run orthogonally. – Seb Jul 22 at 11:06

Initializer are unnamed objects initialized by the initializer list. Outside the body of a function, the object has static storage duration. So it is possible to use the address of such an object. With a little help from variadic macros you can try →

 #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;
 }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.