• 9. memcpy() memccpy() memmove() strcpy() memset()


    部分参考: http://www.cppblog.com/kang/archive/2009/04/05/78984.html

    表头文件: #include <string.h>
    定义函数: void *memcpy(void *dest, const void *src, size_t n)
    函数说明: memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束''而结束

              strcpy()只能用于字符串的copy,而memcpy()可用于任意类型,包括数组、结果体、对象(硬拷贝);此外,memcpy被编译优化为MOVSB, MOVSW等的机器码内存块

              搬动,有的例程上说 memcpy实现是用int类型,每次拷贝4个字节。strcpy是单个字节拷贝的。


    返回值:   返回指向dest的指针

    表头文件: #include <string.h>
    定义函数: void *memccpy(void *dest, const void *src, int c, size_t n);
    函数说明: memccpy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的是,memccpy()如果在src中遇到某个特定值(int c)立即停止复制。
    返回值:   返回指向dest中值为c的下一个字节指针。返回值为0表示在src所指内存前n个字节中没有值为c的字节。

    表头文件: #include <string.h>

    定义函数: void *memmove(void *dest, const void *src, size_t n);
    函数说明:memmove()是从一个缓冲区移动到另一个缓冲区中。 该函数把源字符串拷贝到临时buf里,然后再从临时buf里写到目的地址,增加了一次不必要的开销。性能较memcpy低。
    返回值:   返回指向dest指针。

    当 dest <= src-count  或 dest >= src+count 时,以上三个函数均不会产生覆盖问题,即源数据不会被更改。
    若不在以上范围内,则源数据会被更改。此时,memcpy(), memccpy()的行为是未定义的(有的库考虑了重叠,有的没有考虑,vs貌似考虑了),只能使用更为安全但性能较低的memmove().

    如:
    char a[]={'a','b'};
    char b[]={'c','d','e','f','g','h'};
    memmove(a,b,sizeof(b));

    发现即使a数组指向的空间不够存储数据,也能够移动成功。

    若:

    char *p=b+2;

    memmove(p,b,sizeof(b));

    输出数据会发现b中数据输出已被更改。
    原因|dest - src |<count,出现覆盖问题。也就是说如果外部分配给的空间不足以存储要拷贝的数据时,就有可能出现源数据被覆盖更改的问题。

    如果在使用这些函数时,分配给足够的空间,然后再使用就不会出现覆盖问题。

      表头文件:  #include <string.h>        

      定义函数:   extern void *memset(void *buffer, int c, int count);
      功能: 把buffer所指内存区域的前count个字节设置成字符 c。如' ' , '' 。通常用来赋值字符数组 清空各类型(用0清空)数组

      说明: 返回指向buffer的指针。

     对于int数组,有:

     int a[5];

    使用

    memset(a, 0, sizeof(int)*5); // 可以用0来清空数组a,a中各元素值为 00000000 00000000 00000000 00000000,即 0.

    memset(a, 1, sizeof(int)*5);

    原本想要给a赋值1, 结果会给每个int(4个字节)的每个字节赋值为00000001, 结果每个int值为 00000001 00000001 00000001 00000001,即 16843009,而不是1了。



    自定义这些函数:

    考虑内存重叠的 memcpy 

    void* Memcpy(void* dst , const void* src, size_t n)
    {
        if (dst == NULL || src == NULL)
        {
            return NULL;
        }
        char* pDst = static_cast<char*>(dst); // (char*)dst;
        char* pSrc = const_cast<char*>(static_cast<const char*>(src)); // (char*)src;
        if (pDst > pSrc && (pSrc + n) > pDst) // 只有当dst 在 src 之后,且 (src + n) > dst时, 会将之前copy的内容覆盖掉,故此时因自后向前拷贝
        {
            while (n > 0)
            {
                n--;
                *(pDst + n) = *(pSrc + n);
            }
        }
        else // 其他情况,都从前往后拷贝
        {
            int i = 0;
            while (i < n)
            {
                *(pDst + i) = *(pSrc + i);
                i++;
            }
        }
        return dst;
    }

    strcpy

    char* Strcpy(char* dst, const char* src)
    {
        if (dst == NULL || src == NULL)
        {
            return NULL;
        }
        while ( (*dst++  = *src ++) != ''); // 先取值,再++
        return dst;
    }
  • 相关阅读:
    Linux常用的一些基础命令
    配置Samba(CIFS)
    部署mariadb高可用
    k8s-kuberntets
    获取企业微信的corpID,sercret,access_token,部门设置列表
    Windows系统同步软件
    windows系统ms-17-010 漏洞补丁微软下载地址
    Linux下使用Docker教程
    sqlserver必须安装的组件
    windows系统安全加固方案
  • 原文地址:https://www.cnblogs.com/wenshanzh/p/3299360.html
Copyright © 2020-2023  润新知