I have a problem with filling a flexible array of strings (char *
) inside of a simple struct (the story is, I want to store a message as a string and a list of Redis lists names to send that message to in a struct, to publish to Redis later when a certain callback is called). The array has to be flexible because the number of Redis lists can vary based on a configuration file given to the program.
I can't seem to fill my array properly, I am expecting an array of size 2 in my case and no matter how much memory I allocate, gdb tells me it is of size 1 (I can only see the element of index 0 in the CLion Debugger panel). Two things trouble me :
- It seems like I can assign values to indexes beyond what I intended when allocating memory,
- even worse, I can access memory through elements of the array beyond the supposed array size.
I've seen examples of Flexible Array Members in struct
s but couldn't find an example with FAMs of char *
. Does anyone know what I'm doing wrong here ? Here is an example below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
const char *redis_message;
const char *redis_lists[];
} redis_data;
int main() {
size_t num_lists = 2;
const char *example_redis_lists[num_lists];
// strings with different lengths
example_redis_lists[0] = "foo_bar";
example_redis_lists[1] = "bar";
// this should initialize the struct with an array of size num_lists, right ?
redis_data *data = malloc(sizeof(redis_data) + num_lists * sizeof(char *));
data->redis_message = "Hello World !";
for (size_t idx = 0; idx < num_lists; idx ++) {
const char *string = example_redis_lists[idx];
data->redis_lists[idx] = string;
}
data->redis_lists[2] = "baz_foobar"; // why can I do this ?
data->redis_lists[3] = "i am not supposed to be here";
data->redis_lists[4] = "me neither";
size_t idx = 0;
while (data->redis_lists[idx]) {
// this segfaults if I don't add at least one element past index 1
fprintf(stderr, "index : %zu, value : %s\n", idx, data->redis_lists[idx]);
++idx;
}
return 0;
}
Edit : to clarify, in my actual program the redis lists are indeed present in the array (despite gdb not showing them), but when I iterate it with size_t i= 0; while (data->redis_lists[i]) { send(); ++i; }
I get a segfault because i
equals the length of the array, and it bothers me to add elements to an array which size should be fixed at runtime.