【发布时间】:2021-08-09 17:12:42
【问题描述】:
我有这个链表节点结构,它使用零长度数组来存储内存:
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是一个包含总列表大小的指针)
我正在使用这个函数来分配一个新节点:
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);
}
所以分段错误发生在 memcpy 中,但我不明白为什么,因为我分配了 sizeof(t_list) + size 字节,所以这应该足以对数据执行 memcpy(size)。
此调用发生了段错误:lst_new_element((void *)atoll(argv[1]), sizeof(long long))(argv[1] 是 5)
感谢您的帮助。
【问题讨论】:
-
5(argv[1]) 是否代表在您的环境中可以读取的有效地址? (例如,xv6 中的用户二进制文件将允许这样做) -
argv[1]是"5"(帖子里写的) -
@PaulOgilvie 我正在使用zero-length arrays
-
不确定但是...对于灵活的数组成员,我写的是
[]- 不是[0] -
@BitTickler 相反,在过去,人们使用
char arr[1];之类的东西作为最后一个成员,然后疯狂地将其转换为某个指针或越界访问它。这被称为“结构黑客”,是奇怪错误和损坏代码的常见来源。 Afaik gcc 在 90 年代中期发明了零长度数组作为对抗“结构黑客”的方法。