人快不行了,最近连续性失眠,憔悴啊。这样透支生命,还没活到30岁就会没命的!我还要一直写C++程序呢~~
现在M$已经不推荐使用此函数,取而代之的是memcpy_s, wmemcpy_s.这样就解决了缓冲区溢出问题。安全性也就提高了,M$有那么多攻击它的人,能不防备么?作为使用库的程序员而言,这也带来了无尽的快乐!来看看实现吧
1: /****
2: T* memcpy(T *pDest, T *pSrc, unsigned int uLen)
3:
4: Purpose:
5: 把pSrc赋值到pDest缓冲区中,如果pDest和pSrc内存重叠,则行为未定义
6:
7: Entry:
8: T *pDest - pDest
9: T *pSrc - pSrc
10: unsigned int uLen - max number of bytes to search
11:
12: Exit:
13: pDest叠加后的地址
14:
15: Uses:
16:
17: Exceptions:
18:
19: ***/
20: template<typename T>
21: inline T* tMemCpy(T *pDest, T *pSrc, unsigned int uLen)
22: {
23: while( uLen )
24: {
25: *pDest++ = *pSrc++;
26: --uLen;
27: }
28:
29: return pDest;
30: }
31:
32: template<typename T>
33: inline int tMemcpyS(T *pDest, unsigned int uSizeInBytes, T *pSrc, unsigned int uCnt)
34: {
35: if( uCnt == 0 )
36: {
37: /* nothing to do */
38: return 0;
39: }
40:
41: /* validation section */
42: _ASSERT(pDest != NULL);
43: if( pSrc == NULL || uSizeInBytes < uCnt )
44: {
45: _ASSERT(pSrc != NULL);
46: _ASSERT(uSizeInBytes >= uCnt);
47:
48: /* useless, but prefast is confused */
49: return -1;
50: }
51:
52: tMemCpy(pDest, pSrc, uCnt);
53: return 1;
54: }
看到了吧,其实memcpy_s也是利用memcpy实现的,只是对缓冲区进行了有效性检查。当然memcpy是没有考虑内存重叠的,而memmove倒是一个不错的选择
测试
1: volatile tChar str1[] = _T("aabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc");
2: volatile tChar str2[1024] = {0};
3:
4: volatile const DWORD dwCount = 10000000;
5:
6:
7: DWORD dwLast = 0;
8: {
9: CCYPerformance timer(dwLast);
10: for(DWORD i = 0; i < dwCount; ++i)
11: {
12: CY_CRT::tMemCpy(str2, str1, sizeof(str1) / sizeof(str1[0]));
13: }
14: }
15: cout << dwLast << endl;
16:
17: dwLast = 0;
18: {
19: CCYPerformance timer(dwLast);
20: for(DWORD i = 0; i < dwCount; ++i)
21: {
22: ::memcpy((void *)str2, (const void *)str1, sizeof(str1) / sizeof(str1[0]));
23: }
24: }
25: cout << dwLast << endl;