為什麼存在動態記憶體分配?
我們目前所掌握的記憶體開闢方式例如
int a=20
char arr[10]=
這些開闢的空間都是在棧上開闢的
這樣開闢空間的方式有兩個特點:
1.空間開闢的大小是固定的
2.陣列在宣告的時候,必須指定陣列長度,它所需要的內存在編譯的時候分配
但是對於空間的需求,不僅僅是上述的情況,有時候我們需要的空間的大小在程式執行的時候才知道,那陣列的編譯時開闢空間的方式就不滿足了,我們就只能試試動態記憶體開闢了
下面我介紹幾個動態記憶體函式
一、malloc
二、calloc
三、realloc
棧區:區域性變數、函式形參
堆區:動態記憶體分配的malloc free,realloc,calloc
靜態區:全域性變數,靜態變數
一、malloc
void* malloc(size_t size)
空間的開闢
//malloc(返回值為void*)
int main()
;//在棧區上申請了40的位元組的空間
//動態記憶體開闢 - 堆區
int* p = (int*)malloc(40);//將void*強轉為int*,表示希望將40個位元組的空間當成乙個有10個整形的陣列
int i;
if (p == null)
else }
return 0;
}
動態記憶體的**:
1.程式結束的,會自動**
2.手動**(常用)
注意:一般malloc和free成對出現,分配完要記得**,不然會造成記憶體浪費
//malloc(返回值為void*)
int main()
;//在棧區上申請了40的位元組的空間
//動態記憶體開闢 - 堆區
int* p = (int*)malloc(40);//將void*強轉為int*,表示希望將40個位元組的空間當成乙個有10個整形的陣列
int i;
if (p == null)
else
//不再使用p指向的動態記憶體
//手動釋放動態開闢的記憶體
free(p);
p = null;
} return 0;
}
注意:若引數size為0,malloc的標準行為是未定義的,這就取決於當前的編譯器怎麼做了
void* free(void ptr)
二、calloc
void* calloc(size_t num,size_t size)
//calloc
int main()
else
free(p);
} return 0;
}
編譯執行結果為
這說明calloc函式已經自動幫我們開闢的空間初始化為0了,這也是calloc和malloc的唯一區別,當然,也要注意兩個函式的引數之間的區別
三、relloc
void* relloc(void* memblock,size_t size)
注意:第二個引數是要開闢空間的位元組數!
//realloc
#includeint main()
else
free(p);
//空間不夠了,增加空間
int *ptr = (int*)realloc(p, 80);//調整空間大小
if (ptr != null)
for (i = 0; i < 20; i++)
free(p);//釋放
p = null;
} return 0;
}
常見問題
1.對空指標的解引用操作
//對空指標的解引用操作
#includeint main()
2.對動態開闢空間的越界訪問
3.對非動態開闢記憶體使用free釋放
4.使用free釋放一塊動態開闢記憶體的一部分
5.對同一塊動態記憶體多次釋放
6.動態開闢記憶體忘記釋放(記憶體洩漏)
動態記憶體管理
首先應該明白物件的三種內部的儲存方式 自動儲存,靜態儲存,和動態儲存。當執行離開當期程式塊的時候,堆疊指標返回到它進入程式塊 之前的地方,有效的銷毀了那個程式塊的自動變數。重新進入這個塊會再次建立所有的自動變數。靜態物件宣告或者在檔案域中。動態物件是存在系統呼叫 的在執行期中建立並且儲存在堆中,這是...
動態 記憶體管理
定義變數時,必須制定其資料型別和名字。而動態建立物件時,只需指定其資料型別,而不必為該物件命名。取而代之的是,new表示式返回指向新建立物件的指標,我們通過該指標來訪問此物件。int i int pi new int 這個new表示式在自由儲存區中分配建立了乙個整型物件,並返回此物件的位址,並用該位...
動態記憶體管理
c語言使用malloc calloc realloc free進行動態記憶體管理。void test c 通過new和delete動態管理記憶體。new delete動態管理物件。new delete動態管理物件陣列。void test void test int globalvar 1 stati...