1、C語言中使用malloc/calloc/realloc/free進(jìn)行動(dòng)態(tài)內(nèi)存管理,malloc/calloc/realloc用來在堆上開辟空間,free將申請的空間釋放掉。 1)malloc 原型:void * malloc(size_t size); 該函數(shù)將在堆上分配一個(gè)size byte大小的內(nèi)存。它分配的單原完全按字節(jié)大小計(jì)算,因此如此分配N個(gè)單原的student_t,那么要這樣實(shí)現(xiàn):(stdent_t )malloc(N sizeof (student_t)); (可用memset初始化) 2)calloc 原型:void* calloc(size_t size, int count); 該函數(shù)解決了上面的函數(shù)的不足,它將分配count個(gè)size大小的單原,因此在便用此函數(shù)的時(shí)候就會(huì)很方便,比如對上面的例子就可以:(student_t *)calloc(sizeof(t_student), N)就可以了。這樣使用就會(huì)很清晰的知道分配的內(nèi)存是一種什么樣的邏輯方式。(會(huì)將申請的內(nèi)存空間初始化) 3)realloc 改變原有內(nèi)存空間的大小,若不能改變,則會(huì)開辟一段新的內(nèi)存,將原有內(nèi)存的內(nèi)容拷貝過去,不會(huì)對新開辟的空間進(jìn)行初始化。 4)_alloc 使用_alloc在棧上動(dòng)態(tài)開辟內(nèi)存,棧上空間具有函數(shù)作用域,在函數(shù)結(jié)束后系統(tǒng)自動(dòng)回收,不用用戶管理。
注意:堆上的內(nèi)存需要用戶自己管理,也就是說用戶動(dòng)態(tài)malloc/calloc/realloc的空間,必須自己free掉,否則會(huì)造成內(nèi)存泄漏。 2、常見的內(nèi)存泄漏
void MemoryLeaks(){ //1.內(nèi)存申了忘記釋放 int *pTest = (int *)malloc(10*sizeof(int)); assert(NULL != pTest); Do(); //2.程序邏輯不清,以為釋放了,實(shí)際內(nèi)存泄漏 int *pTest1 = (int *)malloc(10*sizeof(int)); int *pTest2 = (int *)malloc(10*sizeof(int)); Do(); pTest1 = pTesr2; free(pTest1); free(pTest2); //3.程序誤操作,將堆破壞 char *pTest3 = (char *)malloc(5); strcpy(pTest3,"Memory Leaks!"); free(pTest3); //4.釋放是傳入的地址和申請時(shí)的地方不同 int *pTest4 = (int *)malloc(10*sizeof(int)); assert(NULL != pTest4); pTest4[0] = 0; pTest4++; Do(); free(pTest4);}1、C++中使用new和delete運(yùn)算符進(jìn)行動(dòng)態(tài)內(nèi)存管理。 【new作用】 調(diào)用Operator new分配空間。 調(diào)用構(gòu)造函數(shù)初始化對象。 【delete作用】 調(diào)用析構(gòu)函數(shù)清理對象 調(diào)用operator delete釋放空間 【new[]作用】 調(diào)用operator new分配空間。 調(diào)用N次構(gòu)造函數(shù)分別初始化每個(gè)對象。 【delete[]作用】 調(diào)用N次析構(gòu)函數(shù)清理對象。(N是new[ ]出來的) 調(diào)用operator delete釋放空間

2、C++的其他內(nèi)存管理接口(placement版本) void * operator new (size_t size); void operator delete (size_t size); void * operator new [](size_t size); void operator delete[] (size_t size); 1) operator new/operator delete operator new[]/operator delete[] 和 malloc/free用法一 樣。 2)他們只負(fù)責(zé)分配空間/釋放空間,不會(huì)調(diào)用對象構(gòu)造函數(shù)/析構(gòu)函數(shù)來初始化/清理對象。 3)實(shí)際operator new和operator delete只是malloc和free的一層封裝。
void Test() { int *p1 = new int; //動(dòng)態(tài)分配4個(gè)字節(jié)(1個(gè)int)的空間單個(gè)數(shù)據(jù) int *p2 = new int(2); //動(dòng)態(tài)分配4個(gè)字節(jié)(1個(gè)int)的空間并初始化為2 int *p3 = new int[2]; //動(dòng)態(tài)分配8個(gè)字節(jié)(2個(gè)int)的空間 delete p1; delete p2; delete[] p3; }
注意:new和delete、new[ ]和delete[ ]要匹配使用,否則會(huì)造成內(nèi)存泄漏甚至崩潰的問題。 棧: 非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等等,棧是向下增長的。 數(shù)據(jù)段: 存儲(chǔ)全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù)(包括局部靜態(tài)變量) 堆: 程序運(yùn)行時(shí)的動(dòng)態(tài)內(nèi)存分配,可以向上增長的。 代碼段: 可執(zhí)行的代碼和只讀常量。 3、malloc/free和new/delete的區(qū)別和聯(lián)系 1)都是動(dòng)態(tài)內(nèi)存管理的入口。 2)malloc/free是C/C++的標(biāo)準(zhǔn)庫函數(shù),而new/delete是C++的操作符 3)malloc/free只是動(dòng)態(tài)的分配內(nèi)存空間/釋放空間。而new/delete除了分配空間還會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù) 4)malloc/free需要手動(dòng)計(jì)算類型大小且返回值為void*,new/delete可以自己計(jì)算類型的大小,返回對應(yīng)類型的指針。
class Array { public: Array(size_t size = 10) :_size(size) , _a(0) { cout << "Array(size_t size)" << endl; if (size > 0) { _a = new int[size]; } } ~Array() { cout << "~Array()" << endl; if (_a) { delete[]_a; _a = 0; _size = 0; } } PRivate: int* _a; size_t _size; }; void Test() { //malloc/free函數(shù)只是動(dòng)態(tài)的分配內(nèi)存空間/釋放空間。 Array* p1 = (Array*)malloc(sizeof(Array)); //new/delete操作符除了分配空間還會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)來初始化和清理。 Array* p2 = new Array; //1個(gè)類類型 Array* p3 = new Array(20); //1個(gè)類類型并初始化為20 Array* p4 = new Array[10]; //10個(gè)類類型 free(p1); delete p2; delete p3; delete[] p4; } int main() { Test(); //程序結(jié)果構(gòu)造函數(shù)和析構(gòu)函數(shù)被調(diào)用12次。 return 0; }4、定位new表達(dá)式 定位new表達(dá)式是在以分配的原始空間中調(diào)用構(gòu)造函數(shù)初始化一個(gè)對象。 new(place_address) type; new(place_address) type(initializer-list); place_address必須是一個(gè)指針,initializer-list是初始化列表。 eg: 利用mallco/free和定位new表達(dá)式來模擬new/delete和new[]/delete[]:
class A { public: A(int a = 2) :_a(a) { cout << "A()" << endl; } void Print() { cout << _a << endl; } ~A() { cout << "~A()" << endl; } private: int _a; }; int main() { //分配1個(gè)A類型空間 A* pa = (A*)malloc(sizeof(A)); new(pa)A(1); //調(diào)用構(gòu)造函數(shù) pa->~A(); //調(diào)用析構(gòu)函數(shù) free(pa); cout << endl; //分配5個(gè)A類型的空間 A* pa1 = (A*)malloc(5 * sizeof(A)); for (int i = 0; i < 5; i++) { new(pa1 + i)A(i); //調(diào)用5次構(gòu)造函數(shù) } for (int i = 0; i < 5; i++) { (pa1+i)->~A(); //調(diào)用5次析構(gòu)函數(shù) } free(pa1); return 0; }結(jié)果如下: 
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注