所需头文件
#include<string.h>
一、memcpy函数
1、功能
从源内存块拷贝非重叠的数据到目标内存块
2、核心特点与行为
(1) 非重叠假定:memcpy 的实现假定源内存区域 (src) 和目标内存区域 (dest) 绝对不会重叠。
(2) 未定义行为 :如果 src 和 dest 的内存区域存在任何形式的重叠,其行为是未定义的。这意味着程序可能会崩溃、产生错误数据,或者看似正常工作。
(3) 实现:通常是从前向后(低地址到高地址)进行拷贝,因为它不需要考虑重叠问题,实现简单高效。
3、示例
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
// 安全的使用场景:拷贝两个独立不重叠的内存块
memcpy(dest, src, strlen(src) + 1); // +1 是为了拷贝字符串结束符 '\0'
printf("dest: %s\n", dest); // 输出: Hello, World!
// 危险的使用场景:重叠拷贝
char data[] = "ABCDEFG";
memcpy(data + 2, data, 5); // 将"ABCDE"拷贝到"CDEFG"的位置
printf("data: %s\n", data); // 输出结果不可预测,可能是 "ABABABA" 等
return 0;
}
二、memmove函数
1、功能
从源内存块拷贝任何数据(包括重叠)到目标内存块
2、核心特点与行为
重叠安全:memmove 会检查 src 和 dest 的位置关系,并自动选择正确的拷贝策略来保证结果的正确性。
策略:
(1) 如果 dest < src (目标在源前面):采用从前向后(低地址到高地址)拷贝。这样可以防止覆盖源区中尚未被拷贝的数据。
(2) 如果 dest > src (目标在源后面):采用从后向前(高地址到低地址)拷贝。这样可以防止覆盖源区中尚未被拷贝的数据。
(3) 如果区域不重叠:任何一种策略都可以,结果与 memcpy 完全相同。
3、示例
#include <stdio.h>
#include <string.h>
int main() {
// 1: 目标地址在源地址之后 (重叠)
char str1[] = "ABCDEFG";
printf("Before memmove (overlap, dest > src): %s\n", str1);
memmove(str1 + 2, str1, 5); // 将 "ABCDE" 移动到 "CDEFG" 的位置
printf("After memmove: %s\n", str1); // 正确输出: ABABCDE
// 2: 目标地址在源地址之前 (重叠)
char str2[] = "ABCDEFG";
printf("Before memmove (overlap, dest < src): %s\n", str2);
memmove(str2, str2 + 2, 5); // 将 "CDEFG" 移动到 "ABCDE" 的位置
printf("After memmove: %s\n", str2); // 正确输出: CDEFGFG
// 3: 完全不重叠 (行为与memcpy一致)
char src[] = "Hello";
char dest[10];
memmove(dest, src, 6); // 拷贝5个字符+'\0'
printf("No overlap: %s\n", dest); // 输出: Hello
return 0;
}
5807

被折叠的 条评论
为什么被折叠?



