C语言设置NULL字节触发Valgrind无效写入错误排查求助
解决Valgrind检测到的Invalid Write错误
嘿,我一眼就看出问题所在了——你这是字符串数组的内存分配计算错误,导致写入末尾NULL指针的时候越界了!
具体哪里错了?
看你第57行的malloc代码:
output_s = malloc((sizeof(char*) * totalSentences) + 1);
这里的逻辑完全搞错了:
- 在64位系统上,
sizeof(char*)是8字节(指针的大小),你需要存储totalSentences个字符串指针,再加上最后一个用来终止的NULL指针,总共需要totalSentences + 1个指针的空间。 - 你现在的写法是
totalSentences * sizeof(char*) + 1,相当于给总指针字节数加了1个字节——这连一个完整的指针(8字节)都存不下!所以当你执行output_s[totalSentences] = NULL时,必然会越界写入到分配的内存块之外,触发Valgrind的Invalid write警告。
怎么修复?
把内存分配的代码改成下面这样就对了:
output_s = malloc(sizeof(char*) * (totalSentences + 1));
这样就分配了足够的空间,刚好能放下totalSentences个字符串指针,再加最后一个终止用的NULL指针,完美匹配后续的写入操作。
额外给你提几个小建议
- 一定要检查malloc的返回值:内存分配可能失败,每次调用
malloc后都要判断是否返回NULL,避免后续操作崩溃:output_s = malloc(sizeof(char*) * (totalSentences + 1)); if (output_s == NULL) { // 分配失败时,要释放已经分配的子字符串内存,避免泄漏 for (int i = 0; i < currentSentence; i++) { free(output_s[i]); } return NULL; } - 子字符串的分配要注意检查:你给每个子字符串分配的
(sizeof(char) * sentences[i]) + 1是对的(加1用来存字符串末尾的\0),但同样要记得检查每个output_s[i]的malloc返回值哦。 - 释放内存要彻底:后续释放
output_s的时候,得先逐个free每个子字符串指针,再freeoutput_s本身,不然会造成内存泄漏。
修复后的效果
改完之后,Valgrind的Invalid write错误应该就消失了,因为你现在分配的内存足够容纳最后那个NULL指针啦。
内容的提问来源于stack exchange,提问作者user3645925
相关产品推荐
相关产品推荐

