C语言中void指针赋值错误致free触发SIGABRT的正确赋值方式
解决free触发SIGABRT的问题:你的指针赋值哪里错了?
先给你拆解下问题根源:你这段代码里的*(int*)&s->val = val;完全搞错了赋值的目标!
s->val是一个void*类型的指针,它指向你用malloc(sizeof(int))申请的那块内存。而你现在取的是s->val这个指针变量本身的地址(&s->val),强制转换成int*后赋值,相当于把val的值直接覆盖了s->val这个指针的内容——比如如果val是10,那s->val就变成了0xA这个无效地址,之后free(s->val)自然会触发SIGABRT,因为你在尝试释放一个根本不是malloc返回的地址。
正确的赋值方式有两种:
方式一:直接转换指针类型后解引用赋值
把s->val(void*)转换成int*,然后给它指向的内存赋值:*(int*)s->val = val;这是最常用的写法,因为void*可以直接转换成其他指针类型,解引用后就能操作它指向的那块int大小的内存。
方式二:用memcpy拷贝值
如果你想更严谨(或者在一些类型转换容易出错的场景),可以用memcpy把val的内容拷贝到目标内存:memcpy(s->val, &val, sizeof(int));这种方式不需要指针类型转换,直接按字节拷贝,适合复杂类型或者避免类型转换歧义的情况。
修正后的完整代码:
typedef struct{ void *val; }struct_t; void test(int val) { struct_t *s = malloc(sizeof(struct_t)); s->val = malloc(sizeof(int)); // 替换成正确的赋值方式二选一 *(int*)s->val = val; // 或者 memcpy(s->val, &val, sizeof(int)); free(s->val); // 别忘了也free掉s本身,不然会内存泄漏! free(s); }
另外提醒一句:你原来的代码还漏了free(s),会造成结构体本身的内存泄漏,记得补上。
内容的提问来源于stack exchange,提问作者Edwin Skeevers
相关产品推荐
相关产品推荐

