memset 的效率以及原始碼分析

2021-07-05 08:35:33 字數 1307 閱讀 7954

void *memset(void *s, int ch, size_t n);

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

不知道有沒有像我一樣把memset當作萬能的初始化工具,例如:

int arr[n];

memset(arr,1,n*sizeof(int));

這樣得到的arr陣列一定不是全0,而是16843009,下面解釋原因。

首先,變數型別的本質只是標誌從某一記憶體位址開始讀取的位數,強制轉換就是改變讀取位數的大小。

下面來看memset的實現:(**來自《c標準庫》p398)

[cpp]view plain

copy

void *(memset) (void *s,int c,size_t n)    

第3行把int型別的c轉換成unsigned char型別,意味著截去c的高24位,只保留低8位。第4行把s當作unsigned char*型別,也就是說su中的每乙個元素按8位計算。

現在來看看文章開頭的那個**會做什麼。

c的二進位制 : 00000000000000000000000000000001(32位)

1、c轉換為unsigned char 後:00000001(8位)

2、將指標su(unsigned char型別)的每一元素(8位)賦值為00000001,迴圈4n次。

3、memset()結束後,arr的每個元素按照int型別讀取,讀出來的就是1000000010000000100000001,十進位制就是16843009。

不過如果是memset(arr,0,n*sizeof(int));的話可以使用,因為32位都是0

再來說memset()的效率問題。使用memset函式與將上面的函式**寫在自己的程式裡是不一樣的,c標準庫中的memset對cache的利用做了優化,具體的在《c專家程式設計》151頁有解釋(其實是我沒看懂),這裡給出測試:

[cpp]view plain

copy

#include 

#define maxsize 100000

int main()  

return 0;  

}  

程式裡的注釋部分與memset行分別使用,結果是使用memset的程式執行時間大約為0.1s,而用for迴圈的程式要3s多。

綜上:memset()可以用在字元陣列的初始化以及類似於memset(arr,0,n*sizeof(int));的情況,效率比手動賦值要高的多。

memset 的效率以及原始碼分析

void memset void s,int ch,size t n 作用 將s所指向的某一塊記憶體中的每個位元組的內容全部設定為ch指定的ascii值,塊的大小由第三個引數指定,這個函式通常為新申請的記憶體做初始化工作。不知道有沒有像我一樣把memset當作萬能的初始化工具,例如 int arr ...

memset 的效率以及原始碼分析

void memset void s,int ch,size t n 作用 將s所指向的某一塊記憶體中的每個位元組的內容全部設定為ch指定的ascii值,塊的大小由第三個引數指定,這個函式通常為新申請的記憶體做初始化工作。不知道有沒有像我一樣把memset當作萬能的初始化工具,例如 int arr ...

memset函式原始碼實現

void memset void dst,int val,size t count 將dst所指向的某一塊記憶體中的前count個 位元組的內容全部設定為val指定的 ascii 值,第乙個值為指定的記憶體位址,塊的大小由第三個引數指定,這個函式通常為新申請的記憶體做初始化工作,其返回值為指向s的指...