天天看點

關于double free的一點點思考

    double free就是程式配置設定一塊記憶體之後,經過使用将這塊記憶體釋放,但并沒有将指向這塊記憶體的所有指針抹零或回收,并在其他部分再次将指向同一塊記憶體單元的指針交給記憶體配置設定器去進行釋放操作。

    經常看到類似 if (p) free(p); 的寫法,目的是為了防止double free, 但是防止double free的關鍵不是在釋放記憶體前判斷指針是不是為空。

    請看以下代碼:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	char *str;

	str = (char *)malloc(100);

	free(str);

	if (str)
	{
		free(str);
	}

	return 0;
}
           

    這段代碼在第二次釋放記憶體前進行了判斷,但是運作中還是會出現double free。原因在于free()函數隻會回收指針所指的記憶體空間,但是在回收後不會把str置為NULL,是以在這裡用if判斷并沒有意義。

    那麼要怎麼樣才能防止double free呢?檢視free()函數說明:

free(釋放原先配置的記憶體)
相關函數 malloc,calloc,realloc,brk
表頭檔案 #include<stdlib.h>
定義函數 void free(void *ptr);
函數說明 參數ptr為指向先前由malloc()、calloc()或realloc()所傳回的記憶體指針。調用free()後ptr所指的記憶體空間便會被收回。假若參數ptr所指的記憶體空間已被收回或是未知的記憶體位址,則調用free()可能會有無法預期的情況發生。若參數ptr為NULL,則free()不會有任何作用。

    注意這句:若參數ptr為NULL,則free()不會有任何作用。這樣就簡單了,隻要每次在free()後把指針置為NULL就可以了。

    在函數中釋放記憶體的話,切忌以下寫法:

#include <stdio.h>
#include <stdlib.h>

void clear(char *str)
{
	free(str);
	str = NULL;
}

int main()
{
	char *str;

	str = (char *)malloc(100);

	clear(str);

	return 0;
}