Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在不复制源数据的情况下实现memmove_C_Memmove - Fatal编程技术网

C 在不复制源数据的情况下实现memmove

C 在不复制源数据的情况下实现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指向的对象中 现在“似乎”部分告诉我们,这只是用来解释可观察到的行为,而不是一个实现实际上必须这样做 但接下

我需要自己实现标准的c函数memmove

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更有帮助。