memmove函数

本文介绍了memmove函数,包括其功能、特点和C语言实现。函数原型是将指定数量的字节从source地址复制到destination,即使两块内存区域重叠也能够正确处理。文章还提供了函数源码示例及经典用法,强调了在使用中应注意避免溢出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数原型
void * memmove ( void * destination, const void * source, size_t num );
  • 功能

    从指针source指向的地址复制num个字节到destination所指向的内存块, 返回destination指向的地址

  • 特点

    允许destination和source内存块重叠, 函数不检查NULL终止字符
    destination和source指针指向的对象类型不影响函数,函数的执行结果总是二进制拷贝

  • 注意

    为了避免溢出,source和destination指向的数组大小至少为num字节


函数源码
ENTRY(memmove)
        pushl   %esi
        pushl   %edi
        movl    12(%esp), %edi    ;edi存储destination
        movl    16(%esp), %esi    ;esi存储source
        movl    20(%esp), %ecx    ;ecx存储num
        pushl   %edi              ;与popl %eax对应,使返回值为destination
        testl %ecx, %ecx        
        jz 2f                     ;如果num为0则退出
        cmpl    %esi, %edi
        jb 1f                     ;如果souce地址小于destination地址,
        addl %ecx, %esi           ;则使用rep movsb指令从esi指向的地址复制ecx个字节到edi指向的地址
        decl %esi                 
        addl %ecx, %edi           ;否则将destination和source跳转到要复制的最后一个字节
        decl %edi                 ;使用std指令改变地址增长方向,反向复制num个字节
        std
      1:
        rep
        movsb
      2:
        cld
        popl    %eax
        popl    %edi
        popl    %esi
        ret
END(memmove)

C语言实现
void *memmove(void *destination, const void *source, size_t num)
{
    assert((destination!=NULL) && (source!=NULL));
    char *des;
    const char *src;
    size_t n;

    des = (char *)destination;
    src = (const char *)source;
    if (des > src)
    {
        for (n = 0; n < num; ++n)
            *des++ = *src++;
    }
    else
    {
        des = des + num - 1;
        src = src + num - 1;
        for (n = 0; n < num; ++n)
            *des-- = *src--;
    }
    return destination;
}

经典用法

从数组中删除元素

int a[5] = {1,2,3,4,5};
memmove(a+1,a+3,2*sizeof(a[0]));
// a[5] = {1,4,5,4,5};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值