为何memcpy允许将多字节数据复制到内存空间更小的变量中?
memcpy越界复制后仍能正常打印的原因
你遇到的情况本质是C语言中的未定义行为,下面拆解具体原因:
1. memcpy本身不做缓冲区边界检查
memcpy的设计逻辑非常直接:它只会严格按照你指定的字节数,从源地址把数据复制到目标地址,完全不会验证目标缓冲区是否有足够空间容纳这些数据。这是C语言的核心设计思路——把内存操作的控制权完全交给程序员,避免额外检查带来的性能开销,代价就是程序员必须自行保证内存操作的安全性。
2. 能正常打印只是“巧合”
你的str1是栈上的局部变量,它后面的内存空间暂时没有被其他变量或程序数据占用,所以当你用memcpy把200字节的str2复制到仅8字节的str1时,超出的字节只是写到了str1后方的栈内存区域,并没有立刻触发程序崩溃。而puts输出字符串的逻辑是直到遇到\0才停止,只要这些越界写入的字节里包含正确的结束符,就能完整输出内容。
但这种“正常”完全不可靠:一旦后续代码使用str1后方的内存(比如定义新局部变量、调用其他函数),就会覆盖这些越界写入的数据,导致输出乱码;更严重的是,越界写入可能覆盖栈上的关键数据(比如函数返回地址),直接引发程序崩溃,甚至产生安全漏洞。
演示代码与输出
代码
// C program to demonstrate working of memcpy #include <stdio.h> #include <string.h> int main() { char str1[8] = "Hello\0"; char str2[200] = "QuizLinkssjdjufuuejjhfgyyryryyryrynshshhsjakskkk\0"; puts("str1 before memcpy "); puts(str1); // Copies contents of str2 to str1 memcpy(str1, str2, sizeof(str2)); puts("\nstr1 after memcpy "); puts(str1); return 0; }
输出
str1 before memcpy Hello str1 after memcpy QuizLinkssjdjufuuejjhfgyyryryyryrynshshhsjakskkk
内容的提问来源于stack exchange,提问作者Subhadip
相关产品推荐
相关产品推荐

