I have this linked list node struct that's using a zero-length array for storing memory:
typedef struct s_list
{
size_t *list_size;
struct s_list *prev;
struct s_list *next;
size_t size;
char data[0];
} t_list;
(list_size is a pointer containing the size of the total list)
And I'm using this function to allocate a new node:
static t_list *lst_new_element(void *data, size_t size)
{
t_list *new_element;
new_element = malloc(sizeof(t_list) + size);
if (!new_element)
return (NULL);
new_element->size = size;
memcpy(new_element->data, data, size); // <--- Segfault occurs here
return (new_element);
}
So the segmentation fault occurs in the memcpy, but I don't understand why because I allocate sizeof(t_list) + size bytes so this should be enough to do a memcpy(size) on data.
The segfault occured with this call: lst_new_element((void *)atoll(argv[1]), sizeof(long long)) (argv[1] is 5)
Thanks for the help.
You're passing a long long value to your function as if it's a valid void *. Your function then attempts to dereference that pointer (which in invalid) in an attempt to copy what it points to. This triggers undefined behavior leading to a crash.
You need to assign the return value of atoll to a local variable, then pass the address of that variable to the function.
long long val = atoll(argv[1]);
t_list *l = lst_new_element((&val, sizeof(long long));
Also, using a 0 length array as the last member of a struct is an extension many compilers use to implement a flexible array member. The standard-compliant way of doing this is to leave the size blank.
typedef struct s_list
{
size_t *list_size;
struct s_list *prev;
struct s_list *next;
size_t size;
char data[];
} t_list;
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