我需要自己实现标准的 c 函数 memmove。
void *memmove(void *str1, const void *str2, size_t n)
在进行实际复制之前,我可以避免将源代码(由 str2 指向)复制到临时缓冲区中吗?
谢谢!
答案 0 :(得分:3)
memmove
的描述说明
复制发生就好像首先将s2指向的对象的n个字符复制到n个字符的临时数组中,该数组不与s1和s2指向的对象重叠,然后将临时数组中的 n 个字符复制到 s1 指向的对象中。
现在“好像”部分说明这只是用来解释可观察到的行为,而不是实现实际上必须这样做。
但有趣的事实是:在大多数情况下,在可移植标准 C 中实现 memmove
实际上不可能而不将整个源复制到临时缓冲区中(您可以避免这样做如果src == dest
,则完全复制)。
如果你逐字符复制,你可以检查哪个指针首先出现在内存中,即如果target > source
意味着你需要反向复制,即从n - 1
和向后复制。
需要注意的是,如果两个指针都指向同一数组的成员,则使用 target > source
严格仅。这不仅仅是理论上的 - 例如,x86 实模式分段内存模型会使指针比较变得困难。
考虑到警告,您可以将两者都转换为 uintptr_t
进行比较并希望最好(并担心最坏)。我相信转换为 uintptr_t
在 x86 实模式下不起作用(即“640 KB 对任何人来说都足够了”模式),但无论如何谁都想为它编程。
答案 1 :(得分:0)
希望以下代码可以帮助您:
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef uint32_t size_t;
void * memmove(void *dst, const void *src, size_t len){
uint8_t *dp = (uint8_t *)dst;
const uint8_t *sp = (const uint8_t *)src;
if(sp < dp && sp + len > dp){
sp += len;
dp += len;
while(len-- > 0){
*--dp = *--sp;
}
}else{
while(len-- > 0){
*dp++ = *sp++;
}
}
return dst;
}