2
typedef struct {
        void *end;
        void *start;
        int size;
        int arrs [];
        } st;


void *doStuff(void *starter, void *ender) {
    st *s = (st *) malloc(sizeof(st));
    s->end = ender;
    s->start = starter;
    int sayz = 1;
    s->size = (int) (ender - starter);
    int a [s->size];
    memset(a, 0, sizeof a);
    s->arrs = a; // This line gives error
    return s;
    }

the line "st->arrs = a;" gives me the "Invalid use of flexible array member" error. Does anybody know how I can save an array inside a structure? The language is C

Ada
  • 21
  • 3
  • You can't copy an entire array with one assignment statement. Use a loop or memcpy. – stark Feb 26 '22 at 00:42
  • See https://stackoverflow.com/questions/3047530/flexible-array-member-in-c-structure for examples – Andrew Henle Feb 26 '22 at 00:42
  • 1
    I don't understand why the diagnostic has to mention that it's a flexible array member. You can't do that with any array. – Kaz Feb 26 '22 at 01:28

2 Answers2

2

This is what you want, assuming starter and ender point to char objects. I've also cleaned up your indenting and formatting.

typedef struct {
    void *end;
    void *start;
    ptrdiff_t size;  // Note that a diff of pointers should be a ptrdiff_t
    int arrs[];
} st;

st *doStuff(void *starter, void *ender) {
    ptrdiff_t size = (char*)ender - (char*)starter; // Calculate size first so it's available to use in malloc
    st *s = malloc(size + sizeof st);
    s->end   = ender;
    s->start = starter;
    s->size  = size;
    memset(s->arrs, 0, size * sizeof s->arrs[0]); // since array is allocated, no need to create a redundant array
    return s;
}
SGeorgiades
  • 1,771
  • 1
  • 11
  • 11
1

A flexible array member is not a pointer; you do not assign an address or an array to it. You allocate space for it as part of the space you allocate for the structure, and then you use it like an array. Change st *s = (st *) malloc(sizeof(st)); to st *s = malloc(sizeof *s + N * sizeof *s->arrs);, where N is the number of elements you want for the array.

Then you can initialize the array to zero with memset(s->arrs, 0, N * sizeof *s->arrs);.

Note that ender - starter is not proper C code. The type of ender and starter is void *, and the C standard does not define the behavior of subtracting pointers to void. GCC does, but this gives you a number of bytes, not, in general, a number of array elements. To subtract ender and starter properly, use (T *) ender - (T *) starter, where T is the type of object they point to.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312