C语言字符串拼接出现多余字符的原因及相关疑问
C语言字符串拼接中的越界与空终止符问题
核心问题根源:缺失空终止符\0
你代码里的char c[3] = "abc";和char d[3] = "def";是错误的——C语言中标准字符串必须以空终止符\0结尾,这是strcpy、strcat、printf("%s")这类函数识别字符串结束的唯一标志。
"abc"实际包含4个字符:'a'、'b'、'c'、'\0',但你只给数组分配了3字节空间,编译器会自动截断最后的\0。这导致c和d不是合法的C字符串,只是普通字符数组。
多余随机字符的成因
- 调用
strcpy(result, c)时,strcpy会从c的内存地址持续读取,直到找到\0才停止。但c本身没有\0,它会继续读取c数组之后的栈内存垃圾数据,直到碰巧遇到某个\0。 strcat同理:它需要先找到result中的\0来确定拼接起始位置,找不到就会往result之后的内存写入;同时读取d之后的垃圾数据拼接到后面。printf("%s")输出时,也是从result起始地址读,直到碰到\0才停止,中间读到的垃圾数据就是你看到的随机多余字符。
这些随机字符的内容,完全取决于程序运行时栈的当前状态——比如局部变量的残留值、函数调用的栈帧数据等,每次运行栈状态可能不同,所以字符也随机。
为什么result能容纳超出声明长度的字符?
这是缓冲区溢出,属于C语言的未定义行为:C语言不会自动检查数组边界,当你往result写入超出其声明长度的数据时,这些数据会覆盖栈上result之后的内存区域。
你看到char result[1]时还能输出abcdef,只是运气好——溢出的数据没有破坏程序的关键栈结构(比如函数返回地址),但这种行为绝对不可靠,随时可能导致程序崩溃、数据损坏。
正确修正方式
- 给字符数组分配足够空间(包含
\0):
推荐用char c[] = "abc";的写法,编译器会自动计算所需长度(含\0),无需手动计数。 - 确保
result的空间足够容纳拼接后的完整字符串(包括最后的\0):
拼接后总长度为strlen(c) + strlen(d) + 1,比如这里至少需要7字节空间。
修正后的示例代码:
#include <stdio.h> #include <string.h> int main() { char c[] = "abc"; char d[] = "def"; char result[7]; // 3+3+1=7,足够容纳拼接后的字符串与\0 strcpy(result, c); strcat(result, d); printf("%s\n", result); // 输出abcdef return 0; }
内容的提问来源于stack exchange,提问作者ojo
相关产品推荐
相关产品推荐

