#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
#include <stddef.h>
void* memcpy_forward(void* dst, const void* src, size_t n) {
uint8_t* d = (uint8_t*)dst;
const uint8_t* s = (const uint8_t*)src;
// 1. 处理非对齐头部(按字节拷贝直到对齐)
while (((uintptr_t)d & (sizeof(uint32_t) - 1)) != 0 && n > 0) {
*d++ = *s++;
n--;
}
// 2. 32位字拷贝(4字节对齐)
uint32_t* dw = (uint32_t*)d;
const uint32_t* sw = (const uint32_t*)s;
while (n >= sizeof(uint32_t)) {
*dw++ = *sw++;
n -= sizeof(uint32_t);
}
// 3. 处理尾部剩余字节
d = (uint8_t*)dw;
s = (const uint8_t*)sw;
while (n-- > 0) {
*d++ = *s++;
}
return dst;
}
// 反向拷贝(处理重叠区域)
static void* memcpy_backward(void* dst, const void* src, size_t n) {
uint8_t* d = (uint8_t*)dst + n - 1;
const uint8_t* s = (const uint8_t*)src + n - 1;
if (n == 0) return dst;
#if 1
// 1. 处理非对齐尾部(按字节拷贝直到对齐)
while (n > 0 && ((uintptr_t)d & (sizeof(uint32_t) - 1)) != 0) {
*d-- = *s--;
n--;
}
// 2. 32位字拷贝(此时d+1和s+1已对齐)
uint32_t* dw = (uint32_t*)(d + 1) - 1; // 关键修正点!
const uint32_t* sw = (const uint32_t*)(s + 1) - 1;
while (n >= sizeof(uint32_t)) {
*dw-- = *sw--;
n -= sizeof(uint32_t);
}
// 3. 处理剩余字节
d = (uint8_t*)(dw + 1) - 1;
s = (const uint8_t*)(sw + 1) - 1;
while (n-- > 0) {
*d-- = *s--;
}
return dst;
#else
while (n-- > 0) {
*d-- = *s--;
}
#endif
return dst;
}
// 安全的统一接口
void* safe_memcpy(void* dst, const void* src, size_t n) {
if (dst == NULL || src == NULL || n == 0) {
return dst;
}
uint8_t* d = (uint8_t*)dst;
const uint8_t* s = (const uint8_t*)src;
// 检测重叠并选择拷贝方向
if (d > s && d < s + n) {
return memcpy_backward(d, s, n);
}
else {
return memcpy_forward(d, s, n);
}
}
int main()
{
{
char buf[32] = "ABCDEFGHIJKLMNOP";
// 1. 测试非重叠
safe_memcpy(buf + 8, buf, 8); // 正确结果:"ABCDEFGHABCDEFGH"
printf("%s\r\n",buf);
}
{
char buf[32] = "ABCDEFGHIJKLMNOP";
//char buf[32] = " ABCDEFGHIJKLMNOP";
//// 2. 测试重叠(需反向拷贝)
safe_memcpy(buf + 2, buf, 5); // 正确结果:"ABABCDEFGH..."
printf("%s\r\n", buf);
}
//{
// char buf[32] = "ABCDEFGHIJKLMNOP";
// // 3. 测试零长度
// safe_memcpy(buf, buf, 0); // 无变化
// printf("%s\r\n", buf);
//}
//{
// char buf[32] = "ABCDEFGHIJKLMNOP";
// // 4. 测试完全重叠
// safe_memcpy(buf, buf, 16); // 无变化
// printf("%s\r\n", buf);
//}
return 0;
}