正確使用memset

2021-08-16 19:37:29 字數 3389 閱讀 1833

本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。

1. memset是以位元組為單位,初始化記憶體塊。

當初始化乙個位元組單位的陣列時,可以用memset把每個陣列單元初始化成任何你想要的值,比如,

[cpp]view plain

copy

char

data[10];  

memset(data, 1, sizeof

(data));    

// right

memset(data, 0, sizeof

(data));    

// right

而在初始化其他基礎型別時,則需要注意,比如,

[cpp]view plain

copy

intdata[10];  

memset(data, 0, sizeof

(data));    

// right

memset(data, -1, sizeof

(data));    

// right

memset(data, 1, sizeof

(data));    

// wrong, data[x] would be 0x0101 instead of 1

2. 當結構體型別中包含指標時,在使用memset初始化時需要小心。

比如如下**中,

[cpp]view plain

copy

struct

parameters ;  

parameters par;  

par.p_x = new

int[10];  

memset(&par, 0, sizeof

(par));  

當memset初始化時,並不會初始化p_x指向的int陣列單元的值,而會把已經分配過記憶體的p_x指標本身設定為0,造成記憶體洩漏。同理,對std::vector等資料型別,顯而易見也是不應該使用memset來初始化的。

3. 當結構體或類的本身或其基類中存在虛函式時,也需要謹慎使用memset。

這個問題就是在開頭專案中發現的問題,如下**中,

[cpp]view plain

copy

class

baseparameters  

};  

class

myparameters : 

public

baseparameters  

;  myparameters my_pars;  

memset(&my_pars, 0, sizeof

(my_pars));  

baseparameters* pars = &my_pars;  

//......

myparameters* my = dynamic_cast

(pars);  

程式執行到dynamic_cast時發生異常。原因其實也很容易發現,我們的目的是為了初始化資料結構myparameters裡的data和buf,正常來說需要初始化的記憶體空間是sizeof(int) * 3 * 2 = 24位元組,但是使用memset直接初始化myparameters型別的資料結構時,sizeof(my_pars)卻是28位元組,因為為了實現多型機制,c++對有虛函式的物件會包含乙個指向虛函式表(v-table)的指標,當使用memset時,會把該虛函式表的指標也初始化為0,而dynamic_cast也使用rtti技術,執行時會使用到v-table,可此時由於與v-table的鏈結已經被破壞,導致程式發生異常。

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

總的作用:將已開闢記憶體空間 s 的首 n 個位元組的值設為值 c。

2。例子

main() 

【這個問題相當大,程式根本就執行不下去了,你這裡的s志向的是

一段唯讀的記憶體

,而你memset又試圖修改它,所以執行時要出錯,修改辦法char *s修改為char s】

函式原型

memset(dist , val,size);

char test[64];

memset(test, 0,sizeof(test))、或者memset(test,'a',sizeof(test))沒有任何問題,可以完成陣列的正確填充。

同比:int test[64];

memset(test,0,sizeof(test))應該能夠將test 陣列的每個元素填充為0,經驗證,同樣可以;

但memset(test,1,sizeof(test)),理論上能夠test陣列的每個元素填充為1,事實是,test陣列中出現的是:0x01010101(十六進製制)。

為什麼填充失敗了?

反過頭來看memset函式說明,memset是採用將val逐字節填充到dist中去。

當陣列為char型別時,sizeof(char)==1,沒有問題;

陣列為int型別時,sizeof(int)==4,memset 會將陣列元素的四個位元組均填充為val,對應數值1,就是00000001

000000010000000100000001,當轉化成二進位制時,就不可能是1了。

所以,使用memset填充陣列時,需要牢記其是逐個位元組填充。

發現memset的這個問題是源於對指標陣列和陣列指標的理解,兩者在c++可謂是相當強大,易於混淆,偶爾撿起來回顧一下,甚好!

鑑於網上諸多關於指標陣列、陣列指標的用法介紹,我就不再獻醜贅述,僅貼上例子,簡單明瞭(其實,網上資源稂莠不齊,錯誤的講解很多,關鍵還需要靠自己驗證,才能明白個中道理)

int _tmain(int argc, _tchar* argv)

for (int i=0;i

int array[8][8];

//陣列指標

int (*arraypointer)[n];

arraypointer=array;

for (int i=0;i

//int p1[100]等價如下:

int *p1=new int [100];

printf("0x%p\n",p1);

for (int i=0;i<100;i++)

delete p1 ;

return 0;

}所說的陣列和int 型別指標等價,是我自己個人的理解,陣列會由編譯器自動分配記憶體,int型別的指標可以由我們控制記憶體的分配。

對指標陣列深入透徹明白以後,利用指標陣列管理類的設計模式也就雲開霧明了;

對陣列指標深入透徹明白以後,利用陣列指標操縱矩陣便再無違和之感了。

鄙人不才、獻醜。

c++,opengl,cg  learning on my way 

正確使用memset

今天做了一道素數打表的題我在使用乙個陣列記錄是否為素數的時候使用了memset,將陣列裡面的數都清為1,代表是素數,不是素數,就改成0,我在判斷這乙個數是否為素數是依據也是是0還是1,結果一直存在問題,經過我一步步的除錯竟然發現了乙個之前從未在意過的bug,memset只能將int型陣列清理成0或 ...

正確使用memset函式

本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。1.memset是以位元組為單位,初始化記憶體塊。當初始化乙個位元組單位的陣列時,可以用memset把每個陣列單元初始化成任何你想要的值,比如,cpp view plain copy print char dat...

老生常談,正確使用memset

前段專案中發現乙個問題,程式總是在某個dynamic cast進行動態轉換時出異常,查了半天才發現問題原來是出在memset的使用上,雖然問題本身顯而易見,但當處於幾十萬行 量級中時,就變得不太那麼容易定位了。本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。1...