C语言使用零长度数组的链表节点调用memcpy触发段错误问题求助
问题根因
参数传递逻辑错误,导致memcpy尝试访问非法内存地址触发段错误
你的调用语句存在根本性的参数类型错误:lst_new_element((void *)atoll(argv[1]), sizeof(long long))中,atoll(argv[1])的返回值是long long类型的数值本身,当argv[1]为5时,atoll返回的就是数值5,你直接将这个数值强转为void*类型,相当于传给data形参的值是地址0x5,而不是存储数值5的内存空间的地址。
memcpy(new_element->data, data, size)的第二个参数要求传入源数据的起始内存地址,地址0x5属于操作系统保护的低地址空间,用户态程序没有访问权限,读取该地址会直接触发段错误,和你为节点分配的内存空间大小没有关系。
修复方案
先将atoll的转换结果存储到局部变量中,再将变量的地址传入函数即可:
long long num = atoll(argv[1]); lst_new_element(&num, sizeof(long long));
额外注意点
- 你当前使用的
char data[0]零长度数组是GCC的扩展语法,C99及之后标准推荐使用柔性数组写法char data[],兼容性更好 - 你分配新节点时没有初始化
list_size、prev、next三个指针,后续链表操作很容易触发野指针问题,建议分配节点后补充这几个字段的初始化逻辑
内容的提问来源于stack exchange,提问作者Fayeure
相关产品推荐
相关产品推荐

