0

How would I do the following for a typedef ?

typedef struct FriendStack {
    bool       is_resizable;
    size_t     max_size;
    Friend*    stack[];      // will have a variable length of friends
} FriendStack;

Is the way to convert this by doing Friend**, or how does that normally work?

carl.hiass
  • 1,526
  • 1
  • 6
  • 26
  • What is wrong with what you have? It's already a `typedef`. Is there an error? Or are you asking how to allocate memory for a variable of this type? Please clarify. – kaylum Feb 01 '21 at 02:54
  • Well, both. Is it possible to do the above having `stack[]` without an explicit size? – carl.hiass Feb 01 '21 at 02:58
  • 6
    This isn't a struct with VLAs. it's a struct with a [*flexible array member*](https://en.wikipedia.org/wiki/Flexible_array_member). anyway, please clarify your question. What you have is feasible and supported by C99 and later standards, a flexible sequence of `Friend*`. If you would rather abandon using a flexible member in favor of a member pointer to pointer you certainly can do that too. – WhozCraig Feb 01 '21 at 02:59
  • 1
    The wording is unclear. What do you mean by "do the above"? You just did it. What do you mean by "convert this": convert it to what, and in what sense? "How does that normally work" - what is "that"? – Nate Eldredge Feb 01 '21 at 03:03
  • @WhozCraig I see, I think that answers my question then, thanks for the feedback – carl.hiass Feb 01 '21 at 03:06
  • "variable length of friends" --> Not quite. That is a "variable length of "friends *". – chux - Reinstate Monica Feb 01 '21 at 03:49
  • @WhozCraig when I try and malloc though for that stack I get: `invalid use of flexible array member`. How do I malloc that data then? – carl.hiass Feb 01 '21 at 05:02
  • Does this answer your question? [What's the need of array with zero elements?](https://stackoverflow.com/questions/14643406/whats-the-need-of-array-with-zero-elements) – phuclv Feb 01 '21 at 10:11
  • duplicate: [Is empty array in the end of the structure a C standard?](https://stackoverflow.com/q/22220263/995714) – phuclv Feb 01 '21 at 10:12

1 Answers1

1

The sole purpose of using a flexible array member as the last member of a struct is to allow data of variable size to be appended directly after the struct in the same memory segment, and then access that data in a well-defined way.

That means that an array of pointers is often not what you want there, but rather an array of data. It could make sense in some special cases to allocate an array of pointers there, but if it does so in this case, I can't tell.

The normal use-case would be this:

typedef struct FriendStack {
    bool       is_resizable;
    size_t     max_size;
    Friend     stack[];
} FriendStack;

size_t n = something_variable;
FriendStack* fs = malloc( sizeof *fs + sizeof(Friend[n]) );
...
free(fs);

Now if the intention is to actually have Friend* stack[] instead, the syntax for allocating it is the same as above, except it becomes sizeof(Friend*[n]) in malloc. And you'd need an additional loop to allocate something for each pointer:

for(size_t i=0; i<n; i++)
{
  fs->stack[i] = malloc(...);
}

But unlike the first version, this creates segmented chunks in multiple locations on the heap, so it is significantly slower and the code turns more complex overall.

Lundin
  • 195,001
  • 40
  • 254
  • 396