realloc 可能導致的記憶體洩露
阿新 • • 發佈:2019-01-29
在良好的程式碼風格中,其中有一項要求就是,一個函式只做一件事情。如果該函式實現了多個功能,那基本上可以說這不是一個設計良好的函式。
今天看C庫中的函式realloc。其原型是void
*realloc(void *ptr, size_t size);函式說明如下:
realloc()
changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be
uninitialized. If ptr is NULL, the call is equivalent to malloc(size); if sizeis equal to zero, the call is equivalent to free(ptr). Unless ptr is
NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is
done.
總結一下,有以下幾種行為:
1. 與名字相符,真正的realloc,引數ptr和size均不為NULL,重新調整記憶體大小,並將新的記憶體指標返回,並保證最小的size的內容不變;
2. 引數ptr為NULL,但size不為0,那麼行為就等於malloc(size);
3. 引數size為0,則realloc的行為為free(ptr);這時原有的指標已經被free掉,不能繼續使用。而此時realloc的返回值為NULL。這意味著不檢查realloc的返回值,直接使用,會導致crash。
看,一個簡單C庫函式,卻賦予了三種行為,所以這個realloc並不是設計良好的庫函式。估計也是為了相容性,才容忍這個函式一直在C庫中。雖然在編碼中,realloc會提供一定的方便,但是也很容易引發bug。
下面就舉兩個例子,來說明一下。
1. realloc第一種行為引發的bug
-
void *ptr = realloc(ptr, new_size);
-
if (!ptr) {
- 錯誤處理
- }
-
void *new_ptr = realloc(ptr, new_size);
-
if (!new_ptr) {
- 錯誤處理。
-
}
- ptr = new_ptr
-
void *new_ptr = realloc(old_ptr, new_size);
原文 http://blog.chinaunix.net/uid-23629988-id-371240.html