zoukankan      html  css  js  c++  java
  • memory库函数的实现

    下面主要对常用的几个memory库函数的实现(memcpy、memmove、memset、memcmp):

    memcpy函数与memmove函数:

    相同点:

      两者实现的功能均为从src拷贝count个字符到dest。

    不同点:

      1、memcpy函数不考虑内存是否有覆盖的问题,也就是说他只负责完成拷贝工作,至于拷贝后的值正确与否,它是不理会的。

      2、memmove函数考虑了内存覆盖的问题:1)当无覆盖情况时,功能及拷贝结果与memcpy函数相同;

                          2)当有内存覆盖时,能够确保拷贝后的值得正确性。

      3、内存无覆盖及有覆盖的情况如下:

    代码实现如下

    //memcpy:内存拷贝函数,从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

    char* my_memcpy(char* dst,const char* src,size_t count)
    {
    assert(dst != NULL);
    assert(src != NULL);
    assert(count <= strlen(src)+1);
    char* pDst = dst;
    const char* pSrc = src;
    while (count--)
    {
    *pDst = *pSrc;
    pDst++;
    pSrc++;
    }
    return dst;
    }
    --------------------------------------------------------------------------------------------------------------------------------------------

    /* memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前

    将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。*/

    char* my_memmove(char* dst,const char* src,size_t count)
    {
    assert(dst != NULL);
    assert(src != NULL);
    assert(count <= strlen(src) + 1);
    char* pDst = dst;
    const char* pSrc = src;
    if (pDst > pSrc + count || pDst < pSrc)//不包含内存覆盖
    {
    //正向拷贝
    while (count--)
    {
    *pDst = *pSrc;
    pDst++;
    pSrc++;
    }
    }
    else//存在内存覆盖问题
    {
    //反向拷贝(从尾到头)
    pDst += count;
    pSrc += count;
    		while (count--)
    {
    *pDst = *pSrc;
    pDst--;
    pSrc--;
    }
    }
    return dst;
    }

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    memset函数:将str所指内存区域的前count个字节设置成字符c。(注:该函数是对字节进行设置

    //memset内存设置函数:将str所指内存区域的前count个字节设置成字符c。

    代码实现如下
    void* my_memset(void* str, int c, int count)
    {
    assert(str != NULL);
    char* pStr = (char*)str;
    while (count--)
    {
    *pStr = c;
    pStr++;
    }
    return str;

    }

      1、情况一:对字符数组进行设置

        int main()
        {
          char a[10];
          memset(a , 0 , 10 );
        }
        数组a是字符型的,字符型占据内存大小是1Byte,而memset函数也是以字节为单位进行赋值的,所以你输出没有问题。

      2、情况二:对整形数组进行设置

        int main()
        {
          int b[10];
          memset(b , 0 , 10 );
        }
        数组b是整型的,而使用 memset是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。而非想要的1。
     
      3、  如果用memset(a,1,20),就是对a指向的内存的20个字节进行赋值,每个都用数1去填充,转为二进制后,1就是00000001,占一个字节。
     
        一个int类型占4字节,合一起是0000 0001,0000 0001,0000 0001,0000 0001,转化成十六进制就是0x01010101,就等于16843009,
        
        就完成了对一个int元素的赋值了。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    //memcmp是比较内存区域str1和str2的前count个字节。该函数是按字节比较的。


    int my_memcmp(const void *str1, const void *str2, size_t count)
    {
    if (str1 == NULL && str2 == NULL)
    {
    return 0;
    }
    const char* pStr1 = (const char*)str1;
    const char* pStr2 = (const char*)str2;
    int res = 0;
    for (pStr1, pStr2; count > 0; ++pStr1, ++pStr2, --count)
    {
    res = *pStr1 - *pStr2;
    if (res != 0)
    break;

    }
    return res;
    }
    
    
  • 相关阅读:
    C++内存泄漏检测拾遗
    利用ACE_Get_Opt解析命令
    ACE Reactor模型学习
    Acceptor模型和Connector模型学习
    IOCP模型示例
    ACE Proactor模型示例
    如何:为 ASP.NET 网页全球化设置区域性和 UI 区域性
    Update Calendar Item In excaheng server by exchange web services
    ASP.NET Security Architecture
    Error message when you visit a Web site that is hosted on IIS 7.0: "HTTP Error 500.19 – Internal Server Error"
  • 原文地址:https://www.cnblogs.com/hanxiaoyu/p/5556933.html
Copyright © 2011-2022 走看看