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