c提供了幾個動態記憶體分配的函式,包含在 stdlib.h 標頭檔案中:
函式原型如下:
void * malloc ( size_t size );
void free ( void *pointer );
malloc 的引數是所需分配記憶體的位元組數byte,size_t 是無符號數(>=0),對於每個malloc返回的指標都要進行檢查(是否為null)
對於有邊界對齊要求的機器,malloc返回的記憶體起始位置始終能夠滿足對邊界對齊要求最嚴格的型別的要求
void * calloc ( size_t num_elements,, size_t element_size );
void realloc ( void *ptr, size_t new_size );
malloc和calloc之間主要區別是:後者在返回指向記憶體的指標之前把它初始化為0。但如果程式只是想把一些值儲存到陣列中,這個初始化過程純屬浪費時間。
calloc和malloc之間另乙個比較小的區別是:它們請求記憶體數量的方式不同。 calloc包括所需元素數量和每個元素的byte數。
使用了realloc之後,就不能再使用指向舊記憶體的指標,而是應該改用realloc所返回的新指標。
如果realloc函式的第乙個引數是null,那麼它的行為就和malloc一樣了。
使用動態記憶體分配時,常常出現錯誤:對null指標進行解引用(*p,需要判斷返回的指標是否有效),對分配記憶體進行操作時越界,釋放並不是動態分配分配的記憶體,試圖釋放一塊動態分配的記憶體的一部分,一塊動態記憶體被釋放之後被繼續使用。
最常見的錯誤:忘記檢查所請求的記憶體是否成功分配。
第二大錯誤:操作記憶體時超過了分配記憶體的邊界。比如,得到的是長度25的陣列,而訪問小標值小於0或者大於24導致兩種問題,
第一種問題:訪問的記憶體可能儲存了其他變數的值,修改後破壞變數,
這種bug很難被發現!
第二種問題:在malloc和free的實現中,它們以鍊錶的形式維護可用的記憶體池,對分配記憶體之外的區域進行訪問可能破壞這個鍊錶,可能產生異常,終止程式。
介面:alloc.h
#include#define malloc // do not invoke malloc directory
#define malloc(num,type) (type *)alloc( (num) * sizeof(type) )
extern void *alloc( size_t size );
錯誤檢查分配器:實現 alloc.c
#include#include#include"alloc.h"
#undef malloc
//undo the malloc declaration before, so we could use malloc again
void *alloc( size_t num )
return new_mem;
}
使用錯誤檢查分配器 a_client.c
#include#include#include"alloc.h"
int *function( size_t num )
int main( int argc, char *argv )
exit( 0 );
}
總結:使用動態記憶體分配失敗時候,我們首先要檢查是否訪問了分配記憶體之外的區域!
傳遞給free的指標必須是從malloc,realloc,calloc函式返回的指標。若是讓free釋放並非動態分配的記憶體可能導致程式立即終止或者異常。
動態分配的記憶體一定要整塊釋放,但是使用 realloc 函式可以縮小一塊動態分配的記憶體,有效釋放它尾部的部分記憶體。
注意,不要訪問被free釋放過的記憶體。
特別是,對乙個指向動態分配的記憶體的指標進行了複製,而且這個指標的拷貝散布在程式的各個地方。我們無法保證當你使用其中乙個指標時它所指向的記憶體是否已經被另外乙個指標釋放。
另一方面,你必須確保程式中所有使用這塊記憶體的地方在這塊記憶體被釋放之前停止對於它的使用!
原型:
void qsort;
其中base是排序的乙個集合陣列,num是這個陣列元素的個數,width是乙個元素的大小,comp是乙個比較函式
可以這麼寫comp:
int comp( const void *a, const void *b )
也可以這麼寫:
int compare_integers( void const *a, void const *b )
動態分配空間,再進行排序
#include#include/*
* qsort invoke this function
*/int compare_integers( void const *a, void const *b )
int main( int argc, char *argv )
/** allocate mem to store the values
*/array = malloc( n_values * sizeof( int ) );
if( array == null )
/** load these numbers
*/for( i = 0; i < n_values; ++i )}/*
* sort for these values
*/qsort( array, n_values, sizeof( int ), compare_integers );
/** print the result
*/printf( "\nthe result is as follows:\n" );
for( i = 0; i < n_values; ++i )
free( array );
exit( 0 );
}
用動態記憶體分配製作乙個字串的拷貝,呼叫程式需要檢查是否分配成功!
記憶體的容量應該比字串的長度多乙個byte,用來儲存 nul 位元組。
分配失敗返回 null
#include#includechar * strdup( char const *string )
c語言動態記憶體分配 C 動態記憶體分配
動態記憶體分配 雖然通過陣列就可以對大量的資料和物件進行有效地管理,但是很多情況下,在程式執行之前,我們並不能確切地知道陣列中會有多少個元素。這種情況下,如果陣列宣告過大,就會造成浪費 宣告過小,就會影響處理。在c 中,動態記憶體分配技術可以保證程式在執行過程中按照需要申請適量記憶體,使用後釋放,從...
C語言動態記憶體分配
c語言動態記憶體分配 動態資料結構可以在執行時靈活新增 刪除或重排資料項。在執行時分配記憶體空間的過程稱為動態記憶體分配。記憶體分配函式如下 malloc 分配所需的位元組大小,並返回指向所分配空間的第乙個位元組的指標 calloc 為元素陣列分配空間,並初始化為零,然後返回指向該記憶體的指標 fr...
C語言 動態記憶體分配
c語言有儲存變數的區域稱之為棧 stack 除此之外 c語言還允許建立自己的動態記憶體區域 以存放一些臨時的資料 這區域稱之為 堆 heap 也就是存放執行時的資料 可以根據程式的需要 向系統申請所需大小的空間 由於未宣告部分定義他們為變數或者陣列因此只能通過指標去訪問 建立記憶體動態分配主要由4個...