操作記憶體利器memset,memmove,memcpy

來源:互聯網
上載者:User

一:函式宣告:void *memset(void *s, int c, size_t n);

memset:將s所指向的某一塊記憶體中的每個位元組的內容全部設定為ch指定的ASCII值,
塊的大小由第三個參數指定,這個函數通常為新申請的記憶體做初始化工作, 其傳回值為指向S的指標。

1.1:普通理解

大家平時用的最多的就是對一個數組進行初始化。

例如

int data[100];

memset(data, 0, sizeof(data)); 

函數目的就是將data數組所有元素初始化為0. 有人經常把第三個參數寫成:sizeof(int) * 100;  其實也是一樣的。具體原因稍後描述。

1.2:值得糾正和注意的地方

1.樣本:memset(data, 1, sizeof(data))。顯然目的是想將data的所有元素初始化成1,經過實驗,發現不對,記憶體中出現大量的16843009。

不是我們想要的1。

原因剖析,memset函數是以位元組為單位進行賦值的,他經常應用在對一個字串的所有元素賦值。

例如

char data[20];

memset(data, '#', sizeof(data));

而樣本1中的data是整型的,使用 memset還是按位元組賦值,就是對data指向的記憶體的100個位元組進行賦值,每個都用ASCII為1的字元去填充,轉為二進位後,1就是00000001,佔一個位元組。一個INT元素是4 位元組,合一起就是00000001000000010000000100000001,就等於16843009,就完成了對一個INT元素的賦值了。這樣賦值完以後,每個數組元素的值實際上是0x01010101即十進位的16843009。你看看你輸出結果是否這樣?所以大家一定要記住memset是以位元組為單位進行複製的。所以前面提到的關於第三個參數的兩種寫法都是正確的,應為他都是這個數組所佔的位元組個數。所以第三個參數你還可以直接寫成100(對於前面那個例子)。
也能感受到memset用於把整型數組初始化為0,完全是對記憶體比較瞭解或者投機取巧的人弄出來的。我們用的時候一定要小心,要理解其原理。不然就會犯很多錯誤。

總結一下,memset其實是對單個位元組操作的。類似於strset。只是strset只能對字串操作。而memset可針對任何類型。切不可亂用。


二:void *memcpy(void *dest, const void *src, int n);

memcpy: 從源src所指的記憶體位址的起始位置開始拷貝n個位元組到目標dest所指的記憶體位址的起始位置中。注意事項:

1.source和destin所指記憶體地區不能重疊,函數返回指向destin的指標。

2.strcpy和memcpy主要有以下3方面的區別。

2.1 複製的內容不同。strcpy只能複製字串,而memcpy可以複製任意內容,例如字元數組、整型、結構體、類等。

2.2 複製的方法不同。strcpy不需要指定長度,它遇到被複製字元的串結束符"\0"才結束,所以容易溢出。memcpy則是根據其第3個參數決定複製的長度。

2.3 用途不同。通常在複製字串時用strcpy,而需要複製其他類型資料時則一般用memcpy

3.如果目標數組destin本身已有資料,執行memcpy()後,將覆蓋原有資料(最多覆蓋n)。如果要追加資料,則每次執行memcpy後,要將目標數組地址增加到你要追加資料的地址。

注意,source和destin都不一定是數組,任意的可讀寫的空間均可,這就是厲害的地方。


三:void *memmove( void* dest, const void* src, size_tcount
);

memmove:由src所指記憶體地區複製count個位元組到dest所指記憶體地區。memmove支援兩端記憶體有重疊部分。因此memmove比memcpy安全。

附memcpy和memmove的原始碼:

void * __cdecl memcpy (        void * dst,        const void * src,        size_t count        ){        void * ret = dst;         /*         * copy from lower addresses to higher addresses         */        while (count--) {                *(char *)dst = *(char *)src;                dst = (char *)dst + 1;                src = (char *)src + 1;        }         return(ret);} void * __cdecl memmove (        void * dst,        const void * src,        size_t count        ){        void * ret = dst;         if (dst <= src || (char *)dst >= ((char *)src + count)) {                /*                 * Non-Overlapping Buffers                 * copy from lower addresses to higher addresses                 */                while (count--) {                        *(char *)dst = *(char *)src;                        dst = (char *)dst + 1;                        src = (char *)src + 1;                }        }        else {                /*                 * Overlapping Buffers                 * copy from higher addresses to lower addresses                 */                dst = (char *)dst + count - 1;                src = (char *)src + count - 1;                 while (count--) {                        *(char *)dst = *(char *)src;                        dst = (char *)dst - 1;                        src = (char *)src - 1;                }        }         return(ret);}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.