Declaring int array inside struct
Asked Answered
G

3

22

In C, I have defined the struct seen below, and would like to initialize it inline. Neither the fields inside the struct, nor the array foos will change after initialization. The code in the first block works fine.

struct Foo {
  int bar;
  int *some_array;
};

typedef struct Foo Foo;

int tmp[] = {11, 22, 33};
struct Foo foos[] = { {123, tmp} };

However, I don't really need the tmp field. In fact, it will just clutter my code (this example is somewhat simplified). So, instead I'd like to declare the values of some_array inside the declaration for foos. I cannot get the right syntax, though. Maybe the field some_array should be defined differently?

int tmp[] = {11, 22, 33};
struct Foo foos[] = {
  {123, tmp},                    // works
  {222, {11, 22, 33}},           // doesn't compile
  {222, new int[]{11, 22, 33}},  // doesn't compile
  {222, (int*){11, 22, 33}},     // doesn't compile
  {222, (int[]){11, 22, 33}},    // compiles, wrong values in array
};
Grenadier answered 22/6, 2013 at 12:0 Comment(1)
You must allocate memory space for *some_array using malloc or calloc functions.Pomace
F
17
int *some_array;

Here, some_array is actually a pointer, not an array. You can define it like this:

struct Foo {
  int bar;
  int some_array[3];
};

One more thing, the whole point of typedef struct Foo Foo; is to use Foo instead of struct Foo. And you can use typedef like this:

typedef struct Foo {
  int bar;
  int some_array[3];
} Foo;
Felishafelita answered 22/6, 2013 at 12:6 Comment(2)
Also, you mention "The fields inside the struct, nor the array foos will change after initialization" then you can prefix their definitions with the "const" prefix. e.g. const int some_array[3];. This will allow assignment but not modification.Crumhorn
@Crumhorn ITYM it will allow initialization but not assignment or modificationIntegrity
I
33

First, there are 2 ways:

  • You know that array's size
  • You don't know that size.

In the first case it is a static programming problem, and it is not complicated:

#define Array_Size 3

struct Foo {
    int bar;
    int some_array[Array_Size];
};

You can use this syntax to fill the array:

struct Foo foo;
foo.some_array[0] = 12;
foo.some_array[1] = 23;
foo.some_array[2] = 46;

When you dont know the array's size, it is a dynamic programming issue. You have to ask the size.

struct Foo {

   int bar;
   int array_size;
   int* some_array;
};


struct Foo foo;
printf("What's the array's size? ");
scanf("%d", &foo.array_size);
//then you have to allocate memory for that, using <stdlib.h>

foo.some_array = (int*)malloc(sizeof(int) * foo.array_size);
//now you can fill the array with the same syntax as before.
//when you no longer need to use the array you have to free the 
//allocated memory block.

free( foo.some_array );
foo.some_array = 0;     //optional

Second, typedef is useful, so the when you write this:

typedef struct Foo {
   ...
} Foo;

it means you replace the "struct Foo" words with this: "Foo". So the syntax will be this:

Foo foo;   //instead of "struct Foo foo;

Cheers.

Intervocalic answered 26/1, 2014 at 13:26 Comment(1)
The dynamic array is described quite well in GCC docs of one of their extensions: arrays of length zero. You can declare an array of length zero as the last member of a struct and place the struct right before the actual array contents in memory. Note that it’s just an extension and standard ways to achieve the same are described there, too.Casual
F
17
int *some_array;

Here, some_array is actually a pointer, not an array. You can define it like this:

struct Foo {
  int bar;
  int some_array[3];
};

One more thing, the whole point of typedef struct Foo Foo; is to use Foo instead of struct Foo. And you can use typedef like this:

typedef struct Foo {
  int bar;
  int some_array[3];
} Foo;
Felishafelita answered 22/6, 2013 at 12:6 Comment(2)
Also, you mention "The fields inside the struct, nor the array foos will change after initialization" then you can prefix their definitions with the "const" prefix. e.g. const int some_array[3];. This will allow assignment but not modification.Crumhorn
@Crumhorn ITYM it will allow initialization but not assignment or modificationIntegrity
Y
2

My answer is for the following code section:-

int tmp[] = {11, 22, 33};
struct Foo foos[] = {
  {123, tmp},   // works
  {222, {11, 22, 33}},  // doesn't compile
  {222, new int[]{11, 22, 33}},  // doesn't compile
  {222, (int*){11, 22, 33}},  // doesn't compile
  {222, (int[]){11, 22, 33}},  // compiles, wrong values in array
};

All the above compilation issues is due to it not being compatible with the ANSI standards, the aggregate 'foos' is having subaggregates some of which are bracketed while others are not. So if you remove the internal brackets to represent the array 'tmp' it would compile without fail. For eg.

struct Foo foos[] = {
  {123, tmp},   // works
  {222,  11,22,33 },  // would compile perfectly.
}
Yasminyasmine answered 1/6, 2016 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.