您好,登錄后才能下訂單哦!
在c中,申請(qǐng)動(dòng)態(tài)內(nèi)存是使用malloc和free,這兩個(gè)函數(shù)是c的標(biāo)準(zhǔn)庫(kù)函數(shù),分配內(nèi)存使用的是系統(tǒng)調(diào)用,使用它們必須包含stdlib.h,才能編譯通過(guò)。
malloc后需要檢查內(nèi)存是否分配成功,free則要在指針不為空的情況下才能進(jìn)行。
示例代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *p = (char*)malloc(10);
if ( p == NULL)
{
printf("error\n");
}
strncpy(p, "23456", sizeof(p)-1);
printf("p=%s\n", p);
if ( p != NULL)
{
free(p);
p = NULL;
}
return 0;
}
c++中,申請(qǐng)動(dòng)態(tài)內(nèi)存是使用new和delete,這兩個(gè)關(guān)鍵字實(shí)際上是運(yùn)算符,并不是函數(shù)。
需要注意的是:new的不是數(shù)組的話,則直接delete就好,并且只會(huì)調(diào)用一次析構(gòu)函數(shù),而new[]的話,則需使用delete[]來(lái)釋放,并且數(shù)組中每一個(gè)元素都會(huì)調(diào)用一次析構(gòu)函數(shù),調(diào)用完析構(gòu)函數(shù)再釋放內(nèi)存。
對(duì)于基本數(shù)據(jù)類(lèi)型(無(wú)需構(gòu)造函數(shù))而言new是重載了new運(yùn)算符,調(diào)用了operator new,復(fù)雜數(shù)據(jù)類(lèi)型則在此基礎(chǔ)上還會(huì)調(diào)用構(gòu)造函數(shù),而operator new里面則是調(diào)用的malloc函數(shù),如果調(diào)用malloc失敗,則直接拋出異常;
對(duì)于基本數(shù)據(jù)類(lèi)型(無(wú)需析構(gòu)函數(shù))而言delete是重載了delete運(yùn)算符,調(diào)用了operator delete,復(fù)雜數(shù)據(jù)類(lèi)型則在此基礎(chǔ)上還會(huì)調(diào)用析構(gòu)函數(shù),而operator delete里面則是調(diào)用的free函數(shù)。
char* p = new char[32]();
等同于:
char *p = new char[32];
memset(p,0, 32);
簡(jiǎn)單數(shù)據(jù)類(lèi)型時(shí)delete[]則和delete一樣,沒(méi)區(qū)別。
new[]分配的內(nèi)存只能由delete[]釋放,如果由delete釋放會(huì)崩潰,為什么會(huì)崩潰呢?
假設(shè)指針p指向new[]分配的內(nèi)存,因?yàn)橐?字節(jié)存儲(chǔ)數(shù)組大小,實(shí)際分配的內(nèi)存地址為[p-4],系統(tǒng)記錄的也是這個(gè)地址,delete[]實(shí)際釋放的就是p-4指向的內(nèi)存,而delete會(huì)直接釋放p指向的內(nèi)存,這個(gè)內(nèi)存根本沒(méi)有被系統(tǒng)記錄,所以會(huì)崩潰。
根據(jù)前面new實(shí)現(xiàn)原理說(shuō)的,C++里,如果new分配內(nèi)存失敗,默認(rèn)是拋出異常的。所以,如果分配成功,p == NULL就絕對(duì)不會(huì)成立;而如果分配失敗了,也不會(huì)執(zhí)行 if ( p == NULL ),因?yàn)榉峙涫r(shí),new 就會(huì)拋出異常跳過(guò)后面的代碼。如果你想檢查 new 是否成功,應(yīng)該捕捉異常:
try {
int* p = new int[SIZE];
// 其它代碼
} catch ( const bad_alloc& e ) {
return -1;
}
當(dāng)然,標(biāo)準(zhǔn) C++ 亦提供了一個(gè)方法來(lái)抑制 new 拋出異常,而返回空指針,如下:
int* p = new (std::nothrow) int; // 這樣如果 new 失敗了,就不會(huì)拋出異常,而是返回空指針
if ( p == NULL ) // 像這樣,這個(gè)判斷就有意義了
return -1;
delete失敗可能是因?yàn)閮?nèi)存在之前已經(jīng)delete過(guò)一次了,再次delete就會(huì)失敗,linux下報(bào)錯(cuò):double free or corruption,已放棄。
placement new用于在已經(jīng)分配好的內(nèi)存上,再進(jìn)行二次分配,具體實(shí)現(xiàn)如下:
//假設(shè)有類(lèi)X,成員函數(shù)Do(),代碼如下:
int main()
{
char *buf = new char[sizeof(X)];
X *x = new (buf) X;
x->Do();
x->~X(); //一定要主動(dòng)調(diào)用析構(gòu)函數(shù)去析構(gòu)
delete []buf;
return 0;
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。