memcpy的使用方法总结
1、memcpy 函數用于 把資源內存(src所指向的內存區域) 復制到目標內存(dest所指向的內存區域);拷貝多少個?有一個size變量控制
拷貝的字節數;
函數原型:void *memcpy(void *dest, void *src, unsigned int count);
使用方法:(1)能夠拷貝不論什么類型的對象,由于函數的參數類型是void*(沒有定義類型指針),也就是說傳進去的實參能夠是int*,short*,char*等等,
可是由于函數拷貝的過程是一個字節一個字節的拷貝的,所以實際操作的時候要把void*強制轉化為char*,這樣在指針加的時候才會保證每次加一個字節,呵呵
函數源碼實現:
void *memcpy1(void *desc,const void * src,size_t size)
{
?if((desc == NULL) && (src == NULL))
?{
??return NULL;
?}
?unsigned char *desc1 = (unsigned char*)desc;
?unsigned char *src1 = (unsigned char*)src;
?while(size-- >0)
?{
??*desc1 = *src1;
??desc1++;
??src1++;
?}
?return desc;
}
int _tmain(int argc, _TCHAR* argv[])
{
?int dest[2] = {0};
?const char src[5] = "1234";
?//printf(src);
?memcpy1(dest,src,sizeof(src));
?//*(dest+5) = '/0';
?printf((char *)dest);
?int m = -1;
?return 0;
}
注意事項:(1)void* 一定要返回一個值(指針),這個和void不太一樣!
????????? (2)首先要推斷指針的值不能為空,desc為空的話肯定不能拷貝內存空間,src為空相當于沒有拷貝;所以之間return掉;
????????? (3)""空串是指內容為0,NULL是0,不是串;兩個不等價;
????????? (4)int dest[2] = {0};這是對int 類型的數組初始化的方法;假設是char類型,就用char a[5] = "1234";? 注意數組下標要
?????????????? 多于實際看到的字符數,由于還有'/0'
????????? (5)printf((char *)dest);這句話,是把 char 類型 src 傳到 int 類型的 dest的內存強制轉化成char類型,然后打印出來;
?????????????? 由于直接看int類型的dest是看不到里面的內容的;由于有unsigned char *desc1 = (unsigned char*)desc;所以字符能夠傳
?????????????? 到dest里面保存起來,dest所指向的內存長度4個字節,強制轉化為char 就是把四個字節分成一個一個的字節,這樣就能夠看到
?????????????? 一個個字符了,假設定義成char dest[5] = "1234";就不用轉化;呵呵,表達起來真累人;
????????? (6)memcpy1(dest,src,sizeof(src));注意里面的sizeof(src),這個是包括字符串的結束符'/0'的;所以不用操心printf(dest);
?????????????? 可是假設用memcpy1(dest,src,4);沒有'/0'就要*(dest+5) = '/0';這樣保證是一個完整的字符串;
????????? (7)假設初始化的時候:
?char dest[1024] = "12345666";//{0};
?const char src[5] = "3333";
?????????????? 那么拷貝的時候,假設用memcpy1(dest,src,sizeof(src));則printf(dest);出來是3333
?????????????? 假設memcpy1(dest,src,4);則printf(dest);出來是33335666;由于上面的sizeof(src),包括'/0',所以拷貝過去的字符串以'/0'
?????????????? 結束,就僅僅有3333,而假設傳4個字符,'/0'是第五個字符,那就遇到dest[1024] 的'/0'結束,所以是33335666
?????????????? 字符串的'/0'問題一定要注意啊!!!
實際應用:
unsigned char g_pData[1024] = "";
DWORD g_dwOffset = 0;
bool PackDatatoServer(const unsigned char *pData, const unsigned int uSize)
{
?memcpy(g_pData+g_dwOffset, pData, uSize);
?g_dwOffset += uSize;
?//g_pData += uSize;
?return true;
}
void main()
{
?const unsigned char a[4] = "123";
?PackDatatoServer(a, 3);
?PackDatatoServer(a, 1111);
?int b = -1;
}
PackDatatoServer()函數的作用是把每次的資源內存復制到目標內存里面,并且是累加的拷貝;也就是后一次緊接著上一次的拷貝;
顯然用到了memcpy函數;
實現原理是用到了一個全局變量g_dwOffset 保存之前拷貝的長度,最開始沒有想到這一點,結果每次拷貝都是一次性的,下一次拷貝把
上一次的沖掉了;所以用全局變量記錄拷貝的長度;
第二個須要注意的是,拷貝的過程中注意不要改變目標指針的指向,即目標指針始終指向初始化的時候指向的位置;那么怎么實現累積拷貝呢?
就是用的指針偏移;第一次實現的時候,把g_pData += uSize;寫到了函數里面,這樣寫是可以實現指針位移的目標,可是指針指向也發生改變;
?另外:g_pData += uSize;也有報錯:left operand must be l-value,原因是:把地址賦值給一個不可更改的指針!
比方:
? char?? a[100];??
? char?? *p?? =?? new?? char[10];??
? a?? =?? p;?? //這里出錯,注意了:數組的首地址也是一個常量指針,指向固定不能亂改的~~
???
? char?? *?? const?? pp?? =?? new?? char[1];??
? pp?? =?? a;?? //也錯??
所以既不能改變首地址,又要滿足累積賦值(就是賦值的時候要從賦過值的地方開始向下一個內存塊賦值,想到指針加),所以想到把指針加寫到
函數參數里面,這時就要充分了解memcpy的實現過程,里面是一個一個字符的賦值的,想連續賦值,就要把指針指向連續的內存的首地址,所以,
真的非常不好表達,呵呵,就這樣了,一大推零散的知識。。。
總結
以上是生活随笔為你收集整理的memcpy的使用方法总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Servlet中乱码问题
- 下一篇: 通知传值(NSNotificationC