C 在不复制源数据的情况下实现memmove
我需要自己实现标准的c函数memmoveC 在不复制源数据的情况下实现memmove,c,memmove,C,Memmove,我需要自己实现标准的c函数memmove void *memmove(void *str1, const void *str2, size_t n) 在进行实际复制之前,是否可以避免将源(由str2指向)复制到临时缓冲区中 谢谢 的描述是这样的 复制发生,就像将s2指向的对象中的n个字符首先复制到不与s1和s2指向的对象重叠的n个字符的临时数组中一样,然后将临时数组中的n个字符复制到s1指向的对象中 现在“似乎”部分告诉我们,这只是用来解释可观察到的行为,而不是一个实现实际上必须这样做 但接下
void *memmove(void *str1, const void *str2, size_t n)
在进行实际复制之前,是否可以避免将源(由str2指向)复制到临时缓冲区中
谢谢 的描述是这样的
复制发生,就像将s2指向的对象中的n个字符首先复制到不与s1和s2指向的对象重叠的n个字符的临时数组中一样,然后将临时数组中的n个字符复制到s1指向的对象中
现在“似乎”部分告诉我们,这只是用来解释可观察到的行为,而不是一个实现实际上必须这样做
但接下来有趣的事实是:在大多数情况下,如果不将整个源代码复制到临时缓冲区中(如果src==dest
,则可以完全避免进行复制),实际上不可能在便携式标准C中实现memmove
如果执行逐字符复制,则可以检查内存中哪个指针位于第一位,即如果target>source
,则意味着您需要反向复制,即从n-1开始反向复制
需要注意的是,如果两个指针都指向同一数组的成员,则使用target>source
是严格符合的。这不仅仅是理论上的——例如x86实模式分段内存模型可能会使指针比较困难
考虑到这一点,您可以将两者都转换为uintpttr\t
进行比较,并抱最好的希望(以及最坏的恐惧)。我相信转换到uintptr\t
在x86实模式(即“640 KB应该对任何人都足够”模式)下是不起作用的,但谁会想为它编程呢。的描述是这样的
复制发生,就像将s2指向的对象中的n个字符首先复制到不与s1和s2指向的对象重叠的n个字符的临时数组中一样,然后将临时数组中的n个字符复制到s1指向的对象中
现在“似乎”部分告诉我们,这只是用来解释可观察到的行为,而不是一个实现实际上必须这样做
但接下来有趣的事实是:在大多数情况下,如果不将整个源代码复制到临时缓冲区中(如果src==dest
,则可以完全避免进行复制),实际上不可能在便携式标准C中实现memmove
如果执行逐字符复制,则可以检查内存中哪个指针位于第一位,即如果target>source
,则意味着您需要反向复制,即从n-1开始反向复制
需要注意的是,如果两个指针都指向同一数组的成员,则使用target>source
是严格符合的。这不仅仅是理论上的——例如x86实模式分段内存模型可能会使指针比较困难
考虑到这一点,您可以将两者都转换为uintpttr\t
进行比较,并抱最好的希望(以及最坏的恐惧)。我相信转换到uintptr\u t
在x86实模式(即“640 KB应该对任何人都足够”模式)下不起作用,但谁会想为它编程呢。希望下面的代码可以帮助您:
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;
}
typedef无符号字符uint8\t;
typedef unsigned int uint32\u t;
typedef uint32\u 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;
如果(spdp){
sp+=len;
dp+=len;
而(长度-->0){
*--dp=*--sp;
}
}否则{
而(长度-->0){
*dp++=*sp++;
}
}
返回dst;
}
希望以下代码可以帮助您:
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;
}
typedef无符号字符uint8\t;
typedef unsigned int uint32\u t;
typedef uint32\u 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;
如果(spdp){
sp+=len;
dp+=len;
而(长度-->0){
*--dp=*--sp;
}
}否则{
而(长度-->0){
*dp++=*sp++;
}
}
返回dst;
}
简单问题,快速回答:是。--如果你详细阐述你的问题,展示你到目前为止的情况,以及你的想法,这将有助于得到一个好的答案。@thebusybee,这并不是那么简单。@AnttiHaapala,但问题是“我能…”,这是一个简单的问题,可以用是或否来回答。;-)即使我们研究了问题背后的真正问题,我觉得如果他/她在任务上思考几分钟,然后得出错误的结论,会对OP更有帮助。简单的问题,快速的回答:是的如果你详细阐述你的问题,展示你到目前为止的情况,以及你的想法,这将有助于得到一个好的答案。@thebusybee,这并不是那么简单。@AnttiHaapala,但问题是“我能…”,这是一个简单的问题,可以用是或否来回答。;-)即使我们研究了问题背后的真正问题,我觉得如果他/她在任务上思考几分钟,然后得出错误的结论,会对OP更有帮助。