关于memset,malloc以及free后的野指针误区详解
1.首先來看看memset這個函數 void *memset(void *s, int c, size_t n);
memset函數的功能是將一段內存初始化為某個特定的值,并且初始化內存是以內存為單位的。
memset一般用來將內存初始化為0,如果我們將一段內存初始化為1或者其他值得話就要慎用了。
我們看個最直接的 memset例子就很清楚了。
最后運行的結果為16843009,只是因為memset在初始化的時候是以字節為單位進行初始化的,由于在32的系統中int是四個字節,因此a[0]的值初始化為0x01010101=16843009。
如果將數組類型改為char型的初始化為1則不會出現問題。
2.malloc函數原型為void *malloc(size_t size),一般用來給指針申請內存的,申請的內存存在堆里面,這個申請的內存必須手動釋放系統不會自主釋放。
我們在使用malloc申請內存時,可能申請的內存已經使用過,因此我們在申請完有效內存后我們要習慣性的將內存清0,避免不必要的錯誤。
3.最后我們來看看free函數的誤區
free函數原型為:void free(void *ptr);
free 和delete函數在使用時,它們只是把指針所指的內存給釋放掉,但并沒有把指針本身干掉。
用調試器跟蹤示例程序,發現指針p 被free 以后其地址仍然不變(非NULL),只是該地址對應的內存是垃圾,p 成了“野指針”。如果此時不把p 設置為NULL,會讓人誤以為p 是個合法的指針。
char *p = (char *) malloc(100);
strcpy(p, “hello”);
free( p ); // p 所指的內存被釋放,但是p 所指的地址仍然不變
…
if(p != NULL) // 沒有起到防錯作用
{
strcpy(p, “world”); // 出錯
}
void Func(void)
{
char *p = (char *) malloc(100); // 動態內存會自動釋放嗎?
}
上述例子,試圖讓動態內存自動釋放
我們發現指針有一些“似是而非”的特征:
(1)指針消亡了,并不表示它所指的內存會被自動釋放。
(2)內存被釋放了,并不表示指針會消亡或者成了NULL 指針。
如何杜絕野指針?
“野指針”不是NULL 指針,是指向“垃圾”內存的指針。人們一般不會錯用NULL指針,因為用if 語句很容易判斷。但是“野指針”是很危險的,if 語句對它不起作用。“野指針”的成因主要有兩種:
(1)指針變量沒有被初始化。任何指針變量剛被創建時不會自動成為NULL 指針,它的缺省值是隨機的,它會亂指一氣。所以,指針變量在創建的同時應當被初始化,要么將指針設置為NULL,要么讓它指向合法的內存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指針p 被free 或者delete 之后,沒有置為NULL,讓人誤以為p 是個合法的指針。
總結
以上是生活随笔為你收集整理的关于memset,malloc以及free后的野指针误区详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 萌新小白萌新中软实习day7
- 下一篇: alpha测试和Beta测试有何区别