C语言malloc生成的字符串打印时出现随机奇怪字符如何解决
问题根因
- C语言标准规定,使用
%s格式符输出的字符序列必须以'\0'(空字符)作为结束标记。上述代码仅申请了长度为num的内存空间,填充num个'-'字符后未预留结束符存储位置,也没有手动添加结束标记。printf读取字符串时会持续向后访问内存,直到遇到随机存在的'\0'才会终止,不属于当前申请空间的内存数据会被当作字符串内容输出,因此出现随机异常字符。 - 当num=0时,
malloc(0)属于C标准未定义行为,不同编译器实现可能返回空指针或不可访问的极小内存块,读取该内存属于非法操作,也会导致异常输出。
修复方案
如果需要将生成的字符序列作为字符串使用(用于printf打印、字符串函数处理等场景),按以下步骤修改:
- 申请内存时多分配1字节空间,用于存储结束符'\0'
- 填充完指定长度的字符后,在数组最后一位手动赋值为'\0'
- 补充边界判断避免
malloc(0)的未定义行为,同时增加内存申请成功校验、使用后释放内存的逻辑,避免内存泄漏
修复后示例代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int num = 0; char *tabs; for (; num < 20; num++) { // num为0时直接输出空字符串即可 if (num == 0) { printf("%d | %sEND\n", num, ""); continue; } // 多申请1字节存储结束符 tabs = malloc(num + 1); if (tabs == NULL) { perror("内存申请失败"); return 1; } memset(tabs, '-', num); // 末尾添加字符串结束标记 tabs[num] = '\0'; printf("%d | %sEND\n", num, tabs); // 释放内存避免泄漏 free(tabs); } return 0; }
如果仅需要将固定长度的空白符写入文件,不需要作为字符串处理,可以不用添加结束符,写入时直接指定写入长度即可,例如使用fwrite(tabs, 1, num, fp)即可写入准确长度的字符,不会出现多余内容。
内容的提问来源于stack exchange,提问作者A-fandino
相关产品推荐
相关产品推荐

