I wrote a dynamic array like this:
#include <stdlib.h>
typedef struct {
size_t capacity;
size_t len;
} __dynarray_header;
void* dynarray_new() {
__dynarray_header* header = malloc(sizeof(__dynarray_header));
header->capacity = 0;
header->len = 0;
return header + 1;
}
The dynamic array can be accessed with a [] operation. When resizing, I can use __dynarray_header*)array - 1 to retrieve capacity and length information.
The idea works in small tests. However, GCC warns about breaking strict-aliasing.
I've also found some larger projects segfault without the -fno-strict-aliasing compiler option (with -O3 optimization).
I know what strict-aliasing is, and why my code breaks strict-aliasing.
My question is: Is there a better way to implement a dynamic array supporting both the [] operation and dynamic resizing than the one I showed above?
Extra:
A demo program using this dynamic array:
int* arr = dynarray_new();
arr = dynarray_resize(sizeof(int) * 2);
arr[0] = 1;
arr[1] = 2;
arr = dynarray_resize(sizeof(int) * 4);
arr[2] = 3;
arr[3] = 4;
dynarray_free(arr);
The technique that the C standard foresees for such a thing are flexible arrays, as was already mentionned:
typedef struct {
size_t capacity;
size_t len;
unsigned char data[];
} dynarray_header;
If you allocate (or re-allocate) such a struct with enough space you may access the data element like any unsigned char array. char types may alias any other data type, so you wouldn't have problems with that.
If your compiler doesn't support flexible arrays, just put a [1] in there for data.
BTW, names starting with underscores are reserved in file scope, you are not supposed to use these.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With