I have the following struct
with a flexible array member. However, the code does not compile:
#define INITIAL_CAPACITY 5
typedef struct Object {
int size;
int elements[];
} Object;
int main(void) {
Object* result = calloc(1, sizeof(Object) + sizeof(int)*INITIAL_CAPACITY);
if (result == NULL) {
return;
}
for (int i = 0; i < INITIAL_CAPACITY; i++) {
result->elements[i] = 1;
}
result->size = INITIAL_CAPACITY;
int new_size = 2*result->size;
int* new_elements = calloc(1, sizeof(int)*new_size);
if (new_elements == NULL) {
return;
}
for (int i = 0; i < INITIAL_CAPACITY; i++) {
result[i].entries->key = -1;
}
result->elements = new_elements; // "error: expression must be modifiable lvalue"
}
Why can't I reassign the flexible array member to a new, larger array?
ps- it compiles if I change the flexible array member to instead read int* elements
but I'm not sure why...
A flexible array member is not a pointer, it's part of the original struct. Since you allocated the struct dynamically, you need to use realloc()
to enlarge it.
#define INITIAL_CAPACITY 5
typedef struct Object {
int size;
int elements[];
} Object;
int main(void) {
Object* result = calloc(1, sizeof(Object) + sizeof(int)*INITIAL_CAPACITY);
if (result == NULL) {
return;
}
result->size = INITIAL_CAPACITY;
int new_size = 2*result->size;
Object* new_obj = realloc(result, sizeof(Object) + sizeof(int)*new_size);
if (new_obj == NULL) {
return;
}
result = new_obj;
// zero out the new allocation, like calloc does
memset(&new_obj->elements[result->size], 0, sizeof(int)*(new_size - result->size));
result->size = new_size;
}