交换两个char数组后其中一个变量无法正常输出的原因咨询
问题原因分析与解决
核心问题:缓冲区溢出
你的代码出现异常的根本原因是字符串复制时的缓冲区溢出,具体细节如下:
数组大小的隐式定义
char x[] = "water";:编译器会根据字符串长度自动分配6字节空间(5个字符 + 字符串终止符'\0'),所以sizeof(x)的结果是6。char y[] = "soda";:同理,分配5字节空间(4个字符 +'\0'),sizeof(y)结果为5。
溢出发生的步骤
执行strcpy(y, temp);时:temp中存储的是"water",需要6字节才能完整存储(含'\0')。- 但
y的数组只有5字节,strcpy不会检查目标数组的容量,会持续复制直到遇到源字符串的'\0'。这就导致第6个字节('\0')被写入到y数组之外的内存区域。
溢出的影响
局部变量在栈上通常是相邻存储的,溢出的'\0'刚好覆盖了x数组的第一个字节:- 此前
strcpy(x, y)已经把x设置为soda\0,但x[0]被溢出的'\0'覆盖后,x变成了以'\0'开头的空字符串,printf("%s", x)不会输出任何内容。 y数组中被写入了"water"的前5个字符(没有'\0'),但它后面的内存就是被修改后的x,x[0]是'\0',所以printf("%s", y)会读取到water后停止。- 最终输出就是
water加上后续的6和5,看起来像是只显示了water。
- 此前
为什么y字符数多于x时没问题?
如果y的数组大小大于x的字符串长度,strcpy(y, temp)时,源字符串的所有内容(含'\0')都能被容纳在y的数组范围内,不会发生缓冲区溢出,内存不会被破坏,输出自然正常。
解决方案
- 显式定义足够大的数组:比如把
y定义为char y[10] = "soda";,确保有足够空间存储要复制的字符串。 - 使用安全的字符串复制函数:用
strncpy代替strcpy,并手动添加终止符,避免溢出:strncpy(y, temp, sizeof(y)-1); y[sizeof(y)-1] = '\0'; // 确保字符串以终止符结尾
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

