C语言malloc拷贝字符串后printf输出末尾出现特殊乱码是什么原因?
问题原因分析
C语言字符串强制要求以\0(空终止符)作为结束标记,你的代码没有处理空终止符的存储,是输出乱码的核心原因,具体可拆解为以下几点:
strlen的计数规则是从字符串首地址开始,到首个\0之前的字符总数,不包含\0本身。你传入的常量字符串"abcdef"隐含末尾的\0,但strlen(input)计算得到的size值仅为6,没有计入\0的长度。malloc申请的内存仅为size(6)字节,完全没有预留\0的存储空间。memcpy仅拷贝了前6个字符a~f,没有把原字符串末尾的\0一起拷贝到新内存块中。printf的%s格式符会从传入的地址开始连续输出字符,直到遇到\0才停止。你的str末尾没有合法\0,printf会继续读取str之后的非法内存内容,直到碰巧遇到\0为止,这部分非法内存的未知值输出后就是你看到的特殊乱码字符。
修复方案
只需修改fun函数的两处逻辑即可:
- 申请内存时多分配1字节用于存储
\0 - 拷贝完成后手动在内存块末尾添加
\0
修复后的完整代码如下:
char *fun (char * input) { size_t size= strlen(input); char * str; // 多分配1字节存空终止符 str = (char *) malloc(sizeof(char) * (size + 1)); memcpy(str, input , size); // 手动添加空终止符 str[size] = '\0'; return str; } int main(){ char * temp = "abcdef"; char * ret = fun(temp); printf("%s",ret); // 额外提醒:malloc申请的堆内存需要手动释放,避免内存泄漏 free(ret); return 0; }
内容的提问来源于stack exchange,提问作者user11466982
相关产品推荐
相关产品推荐

