0

I have the following object array:

typedef struct MyStack {
    size_t     size;      // current size of stack
    size_t     max;       // max size of stack
    Item*      stack[];
} MyStack;

And I want to create a stack of ten items, so I do:

MyStack stack = malloc(sizeof MyStack);
stack->size = 0;
stack->max = 10;
stack->stack = malloc(sizeof Item * 10);

Then let's say I fill up the stack -- and I have ten items in it. I want to resize the stack to 15 items. What would be the way to do this, including, obviously copying over the existing 10 items to the new stack? Does the problem by definition mean that at one point in memory I'll have 25 items allocated? (not important here, but I could imagine if someone has a data structure of 2GB and they need to resize it, it could lead to a lot of issues).

carl.hiass
  • 1,526
  • 1
  • 6
  • 26
  • Lookup [`realloc`](https://en.cppreference.com/w/c/memory/realloc), which attempts to reallocate in place if enough contiguous memory is available. Also, `Item* stack[];` declares an array of `Item *`, while `malloc(sizeof Item * 10);` appears to allocate an array of `Item`. – dxiv Feb 01 '21 at 04:04
  • 1
    @dxiv thanks for pointing that out. So it should be: `malloc(sizeof Item* * 10)` ? – carl.hiass Feb 01 '21 at 04:05
  • Right, or `malloc(10 * sizeof *stack->stack)` which is another idiomatic way to write it. – dxiv Feb 01 '21 at 04:10
  • Correction, the above is right for an `Item** stack;` which is how I (mis)read it for some reason, but *not* for a flexible array `Item* stack[];` if that's what you meant. A flexible array is embedded in the parent struct, and is never malloc'd itself. – dxiv Feb 01 '21 at 05:52
  • @dxiv I see, that makes it quite tricky. Are flexible arrays used a lot in practice? – carl.hiass Feb 01 '21 at 05:58
  • I wouldn't say "*a lot*". There are cases where they makes sense (e.g. [Pascal-style strings](https://stackoverflow.com/questions/7648947/declaring-pascal-style-strings-in-c)) but in general it's not the *first* thing you'd think at. And when you *do* use a struct ending with a flex array you pay the price of manual memory management, plus not being able to use it as a member of another struct, or as element of an array. – dxiv Feb 01 '21 at 06:28
  • 1
    You'll want the flexible array member to be type `Item [];` or otherwise it would be no point in using that syntax. – Lundin Feb 01 '21 at 08:02

1 Answers1

1

You just have to add a wrapper that re-allocates your stack and changes its size and max_size values:

void resize(Stack *stack, size_t new_size)
{
    stack->max_size = new_size;
    if(stack->size > stack->max_size)
         stack->size = stack->max_size;
    stack->stack = realloc(stack->stack, sizeof(Item) * new_size);
    if(stack->stack == NULL)
        errx(1,"error while resize");
} 
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Chopin
  • 26
  • 3