0

When I create a char pointer in a structure, I can just assign a string to that value and it works fine. When I attempt to do something similar with an int array, I get compilation warnings, likely due to an incorrect syntax for what I'm trying to do. The values of the data will be static through the entire life of the program:

struct structure
{
    char *name;
    int *data[]; //Likely the issue
};

struct structure value = {
    "Some name",
    {0, 1} //Error is here
};

Whenever I attempt to initialize the value object, I get a single compilation error about making a pointer from an integer without a typecast. My assumption is that the value is expecting a pointer, so I'm asking for the wrong value in the first place.

My question is, how do I declare an int array inside the structure so that my declaration of the value object is still valid?

  • 2
    int *data; Why the brackets? – RSon1234 Mar 05 '17 at 23:34
  • http://stackoverflow.com/questions/2060974/how-to-include-a-dynamic-array-inside-a-struct-in-c – kalaracey Mar 05 '17 at 23:36
  • @RSon1234 I'm trying to declare it as a "pointer to an array", so that I can have a simple declaration of an array inside of the value object instead of having to use malloc at program initialization. I didn't think that malloc was required, because the actual length of the array is known before compilation. – Darkshadows Mar 05 '17 at 23:46
  • @DavidBowling The array length varies depending on the instance of the structure, but it's static for that one instance of the structure and will never change throughout runtime. I didn't include that part in the OP. That's why I asked, "how do I declare an int array inside the structure so that my declaration of the value object is still valid?" – Darkshadows Mar 05 '17 at 23:54
  • So the length is not known then. Just create the pointer and dynamically allocate – RSon1234 Mar 05 '17 at 23:57
  • 2
    @RSon1234 an array is not a constant pointer. – M.M Mar 05 '17 at 23:59
  • my mistake. You are correct – RSon1234 Mar 06 '17 at 00:03
  • @DavidBowling So, how does C handle variable-length strings inside of a struct, which are just an array of chars, then? Does it automatically pad the length to the longest string, or is it a pointer that starts at the first character then goes all the way to a null character before stopping? If either of those are the case, why can't I do the same thing for an array of ints? – Darkshadows Mar 06 '17 at 00:05
  • How will you know the length of the array as you pass an instance of the struct to a function? – Jim Rogers Mar 06 '17 at 00:08

3 Answers3

3

You can write:

struct structure
{
    char *name;
    int *data;
};

struct structure value = {
    "Some name",
    (int[]){0, 1}
};

Of course you will also need to employ some other method of knowing how many ints are actually in the array later on when you come to access it.

Note that if this code occurs inside a function, the int array will stop existing when the function returns. (Unlike the string literal)

M.M
  • 138,810
  • 21
  • 208
  • 365
  • This is exactly what I was looking for. Slight increase to the complexity of the structure, but I don't have to malloc at program start. I knew there was a way to do this without malloc, since I'm doing this with values that are known beforehand. – Darkshadows Mar 06 '17 at 00:33
2

The notation with [] in a structure is a 'flexible array member' (FAM). Your structure contains a FAM of type int *, so the values in the array are pointers to int. You said you want an array of int; that would be int data[];.

According to the C standard, you can't initialize the FAM portion of a structure with a FAM. You could initialize the rest of the structure, but the FAM component would be empty, and there would be no way to add a FAM component to that structure.

You would need to do something like this — dynamically allocating the structure and the space for the array:

struct structure
{
    char   *name;
    size_t  size;
    int     data[];
};

int data[] = { 0, 1 };

struct structure *value = malloc(sizeof(*value) + sizeof(data));

if (value != 0)
{
    value->name = "Some name";
    value->size = sizeof(data) / sizeof(data[0]);
    memcpy(value->data, data, sizeof(data));
    …code using value…
    free(value);
}

I added the size member to the structure since code using it would need to know the size of the array somehow.

The following code demonstrates that GCC allows initialization of a FAM unless you tell it to follow the standard pedantically:

#include <stddef.h>

struct structure
{
    char   *name;
    size_t  size;
    int     data[];
};

struct structure value = { "Some name", 2, { 0, 1 } };

GCC (tested with 6.3.0 on a Mac running macOS Sierra 10.12.3) allows the initialization unless you tell it to be pedantic:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror           -c fam13.c
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -pedantic -c fam13.c
fam13.c:10:44: error: initialization of a flexible array member [-Werror=pedantic]
 struct structure value = { "Some name", 2, { 0, 1 } };
                                            ^
fam13.c:10:44: note: (near initialization for ‘value.data’)
cc1: all warnings being treated as errors
$

It would work similarly with the variable definition inside a function.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1
  1. You can't just give a value to an uninitiallized / null pointer; you need to use malloc to allocate memory for both of them.

  2. Just define it as int *data.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
t.elazari
  • 300
  • 2
  • 11