C语言char**结构体成员初始化触发valgrind Invalid Write错误如何解决?
问题原因
- 核心错误是
init函数中为结构体分配内存时,malloc传入的大小参数不符合实际需求:
你的typedef将mystr定义为指向struct mystr结构体的指针类型,sizeof(mystr*)计算得到的是「指针的指针」的大小(64位系统下通常为8字节,32位下为4字节),但你实际需要分配的是完整的struct mystr结构体实例的内存。当前错误写法分配的内存空间小于结构体实际需要的大小时,后续给(*m)->str赋值就会越界写入未申请的内存,触发valgrind的invalid write报错。
即便当前结构体仅包含一个指针成员,看起来分配的大小刚好匹配,这种写法也是不符合规范的,一旦后续扩展结构体新增成员,或者在特殊架构下结构体对齐后的大小和指针大小不一致,必然会出现内存越界问题。
修复方案
将init函数中第一行的malloc参数修改为正确的结构体大小即可,推荐两种写法:
- 显式指定结构体类型:
*m = malloc(sizeof(struct mystr));
- 更安全的无类型写法,自动匹配指向对象的大小,避免手动写类型出错:
*m = malloc(sizeof(**m));
(说明:*m是mystr类型即结构体指针,**m就是实际的struct mystr结构体实例,sizeof(**m)会自动获取结构体的正确大小)
修复后的完整init函数示例:
void init(mystr* m){ *m = malloc(sizeof(**m)); (*m)->str = malloc(sizeof(char*)*2); /* 长度为2的字符串动态数组 */ }
额外注意
动态分配的内存需要按逆序释放:先释放结构体内部的str指针指向的动态数组,再释放结构体本身的内存,避免内存泄漏,参考释放函数:
void destroy(mystr* m) { if (m == NULL || *m == NULL) return; free((*m)->str); free(*m); *m = NULL; }
内容的提问来源于stack exchange,提问作者JamesTheProg
相关产品推荐
相关产品推荐

