You could have the allocator provide a realloc function so you dont have to handle the realloc logic in `array_ensure_capacity`. Would make it easy to provide the C stdlib realloc function instead of handling the logic here. All that logic could be boiled down to just this:
This is small but the spot where you show the Array_Header struct type definition doesn't actually have the name on it. Otherwise, great post and great way of doing this I've never thought of doing dynamic arrays like this.
After playing around with this code, I came across an error in the ensure_capacity function.
When the h->capacity < desired_capacity statement is true and the if statement is skipped, h gets returned, this is wrong. There needs to be an else on that if statement to do h += 1 and then return h so that the array is being returned not the header.
This is kind of related to above but more to my lack of knowledge, could you please explain why the pointer to the ArrayHeader only has to be incremented by one and not sizeof(ArrayHeader)? I think I just don't understand how the ArrayHeader is stored in memory, I thought that increasing the pointer to ArrayHeader would just move the pointer to the next element in the struct.
You could have the allocator provide a realloc function so you dont have to handle the realloc logic in `array_ensure_capacity`. Would make it easy to provide the C stdlib realloc function instead of handling the logic here. All that logic could be boiled down to just this:
const size_t new_size = sizeof(ListPrelude) + new_capacity * item_size;
prelude = prelude->allocator->realloc(prelude, new_size);
That's a good point. I'm going to experiment with that!
Extreme novice c programmer here:
This article has been very educational thus far on how one could manage dynamic arrays in c.
Thank you for posting this! I will be following your content <3
I'm glad to hear it 😊 welcome!
This is small but the spot where you show the Array_Header struct type definition doesn't actually have the name on it. Otherwise, great post and great way of doing this I've never thought of doing dynamic arrays like this.
Thank you for telling me! I will fix that now :)
After playing around with this code, I came across an error in the ensure_capacity function.
When the h->capacity < desired_capacity statement is true and the if statement is skipped, h gets returned, this is wrong. There needs to be an else on that if statement to do h += 1 and then return h so that the array is being returned not the header.
This is kind of related to above but more to my lack of knowledge, could you please explain why the pointer to the ArrayHeader only has to be incremented by one and not sizeof(ArrayHeader)? I think I just don't understand how the ArrayHeader is stored in memory, I thought that increasing the pointer to ArrayHeader would just move the pointer to the next element in the struct.
Thank you for that. I'll have to be more careful in my next post 🤠
As for the question: the reason is because pointer arithmetic varies based on the size of the thing pointed to. Eg:
char *a = ...;
a += 1;
Increments by sizeof(char) which is 1 byte.
So since it's an Array_Header pointer, we increment by sizeof Array_Header.
Ohhh ok that makes sense, I never knew that. Thank you.
Semicolon should be removed in a "do ... while(0)" pattern of a macro! See e.g. https://stackoverflow.com/a/1067238
Awesome post btw! Thanks!!!