make our memcpy and memmove

来源:互联网 发布:java创建多线程数组 编辑:程序博客网 时间:2024/06/05 05:05


/// @file exam_1_1.c/// @brief /**exam_1_1实现memcpy, 解决数据重叠问题.当拷贝点为AA’BB’时,从A’B’拷贝到AB时, 考虑重叠.*/#include <windows.h>#include <stdlib.h>#include <stdio.h>/// @fn memcpy_ex/// @brief Copy source buffer to destination buffer///     This routine does NOT recognize overlapping buffers, and thus can lead///     to propogation.///     For cases where propogation must be avoided, memmove_ex() must be used./// @param void* dst, addr copy to/// @param void* src, addr copy from/// @param size_t count, bytes count copy to dst/// @return void*, dst pointervoid* memcpy_ex(void* dst, void* src, size_t count);/// @fn memmove_ex/// @brief copies a source memory buffer to a destination memory buffer.///     This routine recognize overlapping buffers to avoid propogation.///     For cases where propogation is not a problem, memcpy_ex() can be used./// @param void* dst, addr copy to/// @param void* src, addr copy from/// @param size_t count, bytes count copy to dst/// @return void*, dst pointervoid* memmove_ex(void* dst, void* src, size_t count);void fn_test_memcpy_org(); ///< 测试原始的memcpyvoid fn_test_memmove_ex(); ///< 测试我们自己攒的memmove_exint main(int argc, char** argv){    fn_test_memmove_ex(); ///< ok    printf("\n\n");    fn_test_memcpy_org(); ///< ok    printf("\n\n");    printf("END, press any key to quit\n");    getchar();    /// 经过比对 memmove_ex 和 memcpy,     /// 可以看出, 我们攒的 memmove_ex 和 memcpy 效果相同    /// 保证拷贝正确的关键是判断正向拷贝和反向拷贝的发生的条件         /** run result    fn_test_memmove_ex()    pA     : is cheap, Later equals never.    pA + 12: ter equals never.    pAA    : eap, Later equals never.    pAA+ 12: quals never.    before : talk is cheap, Later equals never.    after1  : talk eap, Later eter equals never.    after2  : talk eap, eap, Later equals never.    fn_test_memcpy_org()    pA     : is cheap, Later equals never.    pA + 12: ter equals never.    pAA    : eap, Later equals never.    pAA+ 12: quals never.    before : talk is cheap, Later equals never.    after1  : talk eap, Later eter equals never.    after2  : talk eap, eap, Later equals never.    END, press any key to quit    */    return 0;}void fn_test_memmove_ex(){    /// 测试我们自己攒的memmove_ex    /// 看看覆盖拷贝时, 是否有问题    /// 当拷贝点为AA’BB’时,从A’B’拷贝到AB时, 考虑重叠.    char cBuf[] = {"talk is cheap, Later equals never."};    char* pA = cBuf + 5;    char* pAA = cBuf + 10;    printf("fn_test_memmove_ex()\n");    printf("pA     : %s\n", pA);    printf("pA + 12: %s\n", pA + 12);    printf("pAA    : %s\n", pAA);    printf("pAA+ 12: %s\n", pAA + 12);    printf("before : %s\n", cBuf);    /// 在vc6Debug下, 单步发现 memmove 和 memcpy下用的都是一个实现    /// 所以 memcpy也可以处理数据重叠的情况    memmove_ex(pA, pAA, 12); ///< 模拟有重叠情况下的拷贝    printf("after1  : %s\n", cBuf);    memmove_ex(pAA, pA, 12); ///< 模拟有重叠情况下的拷贝    printf("after2  : %s\n", cBuf);}void fn_test_memcpy_org(){    /// 测试原始的memcpy    /// 看看覆盖拷贝时, 是否有问题    /// 当拷贝点为AA’BB’时,从A’B’拷贝到AB时, 考虑重叠.    char cBuf[] = {"talk is cheap, Later equals never."};    char* pA = cBuf + 5;    char* pAA = cBuf + 10;    printf("fn_test_memcpy_org()\n");    printf("pA     : %s\n", pA);    printf("pA + 12: %s\n", pA + 12);    printf("pAA    : %s\n", pAA);    printf("pAA+ 12: %s\n", pAA + 12);    printf("before : %s\n", cBuf);    /// 在vc6Debug下, 单步发现 memmove 和 memcpy下用的都是一个实现    /// 所以 memcpy也可以处理数据重叠的情况    memcpy(pA, pAA, 12); ///< 模拟有重叠情况下的拷贝    printf("after1  : %s\n", cBuf);    memcpy(pAA, pA, 12); ///< 模拟有重叠情况下的拷贝    printf("after2  : %s\n", cBuf);}void* memcpy_ex(void* dst, void* src, size_t count){    void * ret = dst;    do     {        if (dst == src) ///< 优化        {            break;        }        /// copy from lower addresses to higher addresses        while (count-- > 0)        {            *((unsigned char*)dst)++ = *((unsigned char*)src)++;        }    } while (0);    return(ret);}void* memmove_ex(void* dst, void* src, size_t count){    void * ret = dst;    do     {        if (dst == src) ///< 优化        {            break;        }        if ((unsigned char*)dst <= (unsigned char*)src             || (unsigned char*)dst >= ((unsigned char*)src + count))        {            /// 如果没有数据覆盖, 正向拷贝            /// Non-Overlapping Buffers            /// copy from lower addresses to higher addresses            while (count-- > 0)            {                *((unsigned char*)dst)++ = *((unsigned char*)src)++;            }        }        else        {            /// 如果有数据覆盖, 反向拷贝            /// Overlapping Buffers            /// copy from higher addresses to lower addresses            (unsigned char*)dst += count - 1;            (unsigned char*)src += count - 1;            while (count-- > 0)            {                *((unsigned char*)dst)-- = *((unsigned char*)src)--;            }        }    } while (0);    return(ret);}


0 0