C语言中valgrind检测到void*变量非法写入的问题排查
问题根源分析与解决
首先,你的代码里存在typedef语法错误,这是导致Valgrind报错的核心原因!
1. typedef的写法完全搞反了
C语言中,typedef的正确格式是:
typedef 原类型 别名;
你写的结构体定义:
struct data{ int n; void * cl; }typedef data;
这是错误的,编译器根本不会把data识别为struct data的别名。同样,struct st_args的typedef也犯了同样的错误:
struct st_args{ int n; }typedef st_args;
2. 错误typedef导致malloc分配空间不足
因为data不是struct data的有效别名,所以在函数f的这行代码里:
struct data *data = malloc(sizeof(data));
这里的sizeof(data)计算的是指针变量data的大小(64位系统下是8字节),而不是struct data结构体的实际大小(sizeof(int) + sizeof(void*),64位下通常是12或16字节,取决于内存对齐规则)。
malloc只分配了8字节,但你的结构体需要更大的空间,所以当执行data->cl = cl;或者data->n = n;时,你实际上在往malloc分配的内存边界之外写数据,这就触发了Valgrind的"Invalid write of size 8"错误。
3. 修正后的代码
首先修正两个结构体的typedef:
// 正确的data结构体typedef typedef struct data { int n; void *cl; } data; // 正确的st_args结构体typedef typedef struct st_args { int n; } st_args;
然后修正函数f中的malloc调用,确保分配足够的结构体空间,同时建议避免变量名和结构体别名混淆:
void f(void *cl, int n){ // 现在可以用sizeof(data)或sizeof(struct data),两者等价 data *data_ptr = malloc(sizeof(data)); if (data_ptr == NULL) { // 别忘了检查malloc是否成功! return; } data_ptr->cl = cl; data_ptr->n = n; }
补充:关于传入的cl为NULL的问题
你提到传入的cl是NULL,但这不是报错的原因——NULL是合法的指针值,写入结构体的void*成员完全没问题,问题的本质还是内存分配不足导致的越界写入。
内容的提问来源于stack exchange,提问作者Zul Huky
相关产品推荐
相关产品推荐

