字符数组的不同赋值方法及代码问题:为何两段打印均无法正常工作?
问题分析:缓冲区溢出引发的未定义行为
咱们一步步拆解这段代码的核心问题,再解释为什么两次printf都会出现异常:
1. 字符串长度与数组空间不匹配
先仔细数一下source的实际内容:"hello folks"包含11个可见字符,但C语言的字符串必须以'\0'(空终止符)结尾,所以编译器初始化source[]时,会自动把它变成一个12字节的数组(11个字符+1个'\0')。
但你定义的destination只有char destination[11];——仅11字节的空间,根本装不下source的12个字节内容。
2. strcpy触发缓冲区溢出
strcpy的工作逻辑是:从源字符串逐个复制字符,直到遇到'\0'才停止。这里destination空间不足,strcpy就会越界写入,把'\0'甚至其他字符写到destination数组之外的内存区域。
而栈上的变量(比如两个循环里的i、source本身)是连续存储的,溢出的数据很可能会破坏这些变量的内存值——这就是C语言里的「未定义行为」,程序的表现会完全不可预测。
3. 为什么两段printf都异常?
- 第一段遍历
source的循环:理论上source是合法的字符串,应该能正常打印,但如果溢出的数据破坏了循环变量i的内存(比如把i的值改成了异常数值),循环就会提前终止、甚至进入死循环,导致打印不完整或者乱码。 - 第二段遍历
destination的循环:因为destination数组里没有正确的'\0'终止符(本该放在第11位的'\0'被写到了数组外面),循环会一直读取超出destination的内存,直到遇到某个随机的'\0',结果就是打印一堆乱码,甚至直接触发程序崩溃。
修复方案
有两种简单可靠的修复方式:
- 直接给
destination分配足够的空间:比如改成char destination[sizeof(source)];,保证和source大小完全一致。 - 使用更安全的字符串复制函数,比如
strncpy(注意手动添加终止符):strncpy(destination, source, sizeof(destination)-1); destination[sizeof(destination)-1] = '\0'; // 手动添加终止符,避免无终止符的情况
内容的提问来源于stack exchange,提问作者Kaihua Hou
相关产品推荐
相关产品推荐

