内存操作函数memcpy和memmove详解

内存操作函数memcpy和memmove详解

  在C/C++中,根据定义,字符串由一个'\0'字节结尾,所以字符串内部不能包含'\0'字符。但是,非字符串数据内部包含'\0'的情况并不少见。你无法使用字符串函数(strcpy,strcat,strcmp等等字符串处理函数)来处理这种类型的数据,因为它们遇到第一个'\0'之后就停止工作。

  因此C/C++中提供了另外一组mem***函数来处理内存操作,它们可以处理包括'\0'在内的任意字节,这些函数都接受一个长度参数。memcpy从源参数向目标参数复制由长度参数指定的字节数。memmove函数执行相同的功能,但它功能更加强大,能够正确处理源参数和目标参数出现内存重叠的情况。但通常由于memmove无法使用某些机器提供的特殊字节-字符串处理指令,所以它可能比memcpy慢一些。

  源参数和目标参数在内存中分布情况分为重叠和不重叠,而重叠又分为源参数在目标参数的前面和源参数在目标参数的后面。memcopy只能处理不重叠和源参数在目标参数的后面的情况,而memmove能处理所有的情况。具体可以参考如下代码:

  

void *memcpy (void *dst, void *src, size_t length)
{
    if (NULL == dst || NULL == src)
        return NULL;
    char *temp_dst = (char*)dst;
    char *temp_src = (char*)src;
    for (size_t len = 0; len < length; ++len) //从前往后复制
    {
        *temp_dst++ = *temp_src++;
    }
    return dst;
}

void *memmove (void *dst, void *src, size_t length)
{
    if (NULL == dst || NULL == src)
        return NULL;
    char *temp_dst = (char*)dst;
    char *temp_src = (char*)src;
    if (temp_src < temp_dst) //从后往前复制
    {
        temp_dst += length - 1;
        temp_src += length - 1;
        for (size_t len = 0; len < length; ++len)
        {
            *temp_dst-- = *temp_src--;
        }
    }
    else //从前往后复制
    {
        for (size_t len = 0; len < length; ++len)
        {
            *temp_dst++ = *temp_src++;
        }
    }

    return dst;
}

 

完整的实现及测试如下:

#include <iostream>
using namespace std;

void *memcpy (void *dst, void *src, size_t length);
void *memmove (void *dst, void *src, size_t length);


void *memcpy (void *dst, void *src, size_t length)
{
    if (NULL == dst || NULL == src)
        return NULL;
    char *temp_dst = (char*)dst;
    char *temp_src = (char*)src;
    for (size_t len = 0; len < length; ++len) //从前往后复制
    {
        *temp_dst++ = *temp_src++;
    }
    return dst;
}

void *memmove (void *dst, void *src, size_t length)
{
    if (NULL == dst || NULL == src)
        return NULL;
    char *temp_dst = (char*)dst;
    char *temp_src = (char*)src;
    if (temp_src < temp_dst) //从后往前复制
    {
        temp_dst += length - 1;
        temp_src += length - 1;
        for (size_t len = 0; len < length; ++len)
        {
            *temp_dst-- = *temp_src--;
        }
    }
    else //从前往后复制
    {
        for (size_t len = 0; len < length; ++len)
        {
            *temp_dst++ = *temp_src++;
        }
    }

    return dst;
}

int main ()
{
    char a[20] = "Hello joel";
    char b[20];
    char *p = NULL;
    p = (char*)memcpy (b, a, 10);
    while ('\0' != *p)
    {
        cout << *p;
        p++;
    }
    cout << "\n";
    p = (char*)memmove (a + 1, a, 10);
    while ('\0' != *p)
    {
        cout << *p;
        p++;
    }
    return 0;
}

 

输出结果为:

Hello joel
Hello joel

转载于:https://www.cnblogs.com/uestcjoel/p/6672663.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值