Malloc分配字符串内存大小错误导致输出异常问题咨询
问题原因分析及解决方案
核心问题原因
- malloc内存未初始化:
malloc从堆上分配的内存不会自动清零,里面保留的是之前内存块的残留数据,也就是你看到的奇怪符号。这些数据是随机的,每次运行可能都不一样。 - 缺少字符串终止符:C语言中,字符串必须以
'\0'(空字符)作为结束标记。你只复制了A和B的字符内容,但没有在拼接后的C末尾添加'\0'。printf("%s")会持续读取内存直到遇到'\0',所以会越界读取你分配的内存之外的垃圾数据,甚至超出申请的内存大小。 - 内存分配不足:你分配的内存大小是
strlen(A)+strlen(B),但没有预留存储'\0'的1个字节空间,导致连终止符都没地方放。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char A[200], B[200]; printf("Enter 2 words or sentences.\n"); // 用fgets替代不安全的gets,同时处理输入的换行符 fgets(A, sizeof(A), stdin); A[strcspn(A, "\n")] = '\0'; // 移除换行符 fgets(B, sizeof(B), stdin); B[strcspn(B, "\n")] = '\0'; size_t lenA = strlen(A); size_t lenB = strlen(B); // 多分配1字节用于存储字符串终止符 char* C = malloc(lenA + lenB + 1); if (C == NULL) { // 必须检查malloc是否成功 perror("malloc failed"); return 1; } // 用标准库函数完成字符串拼接,自动处理终止符 strcpy(C, A); strcat(C, B); printf("%s\n", C); free(C); // 释放堆内存,避免泄漏 return 0; }
额外注意事项
- 永远要检查
malloc的返回值,如果内存分配失败会返回NULL,直接使用会导致程序崩溃。 gets函数已被C标准废弃,它不限制输入长度,极易造成缓冲区溢出,推荐使用fgets替代。- 手动复制字符串时,务必记得在最后添加
'\0';使用标准库的strcpy/strcat/strncat等函数会更安全高效,这些函数会自动处理终止符。
内容的提问来源于stack exchange,提问作者Genata339
相关产品推荐
相关产品推荐

