国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站免費建站 圖標(biāo)seo全網(wǎng)營銷的方式

網(wǎng)站免費建站 圖標(biāo),seo全網(wǎng)營銷的方式,煙臺建網(wǎng)站公司哪家好,seo排名優(yōu)化怎么樣一.C/C內(nèi)存分布 先來回顧一下C語言內(nèi)存分區(qū)示意圖如下: 代碼區(qū): 程序執(zhí)行代碼一般存放在代碼區(qū),字符串常量以及define定義的常量也可能存放在代碼區(qū)。 常量區(qū): 字符串,數(shù)字等常量以及const修飾的全局變量往往存放在…

一.C/C++內(nèi)存分布

先來回顧一下C語言內(nèi)存分區(qū)示意圖如下:

代碼區(qū):

  • 程序執(zhí)行代碼一般存放在代碼區(qū),字符串常量以及define定義的常量也可能存放在代碼區(qū)。

常量區(qū):

  • ?字符串,數(shù)字等常量以及const修飾的全局變量往往存放在常量區(qū)。

全局(靜態(tài))區(qū):

  • 將全局變量和靜態(tài)變量存放在全局(靜態(tài))區(qū):已初始化的全局變量和靜態(tài)變量存放在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量存放在相鄰的另一塊區(qū)域。

堆區(qū):

  • 堆區(qū)由程序員調(diào)用malloc, calloc, realloc等分配函數(shù)進(jìn)行內(nèi)存空間的分配和釋放,按內(nèi)存地址由低地址到高地址增長。

棧區(qū):

  • 棧區(qū)由編譯器自動分配釋放,由操作系統(tǒng)自動管理,無須手動管理;在函數(shù)執(zhí)行時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放。

我們再來看下面的一段代碼和相關(guān)問題 :

int globalVar = 1;//數(shù)據(jù)段/靜態(tài)區(qū)
static int staticGlobalVar = 1;//數(shù)據(jù)段/靜態(tài)區(qū)
void Test()
{static int staticVar = 1;//數(shù)據(jù)段/靜態(tài)區(qū)int localVar = 1;//棧區(qū)int num1[10] = { 1, 2, 3, 4 };//棧區(qū)char char2[] = "abcd";//char2存放在棧區(qū),*char2代表字符串第一個元素存放在棧區(qū)const char* pChar3 = "abcd";//pChar3存放在棧區(qū),*pChar3存放在常量區(qū)int* ptr1 = (int*)malloc(sizeof(int) * 4);//ptr1是個指針存放在棧區(qū),*ptr1指向的內(nèi)容存放在堆區(qū)int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}

小結(jié):

說明:

  1. 棧又叫堆棧--非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等等,棧是向下增長的;
  2. 內(nèi)存映射段是高效的I/O映射方式,用于裝載一個共享的動態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享共享內(nèi)存,做進(jìn)程間通信;
  3. 堆用于程序運行時動態(tài)內(nèi)存分配,堆是可以上增長的;
  4. 數(shù)據(jù)段--存儲全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù);
  5. 代碼段--可執(zhí)行的代碼/只讀常量。

二.C++內(nèi)存管理方式

C語言內(nèi)存管理方式在C++中可以繼續(xù)使用,但有些地方就無能為力,而且使用起來比較麻煩,因此C++又提出了自己的內(nèi)存管理方式:通過new和delete操作符進(jìn)行動態(tài)內(nèi)存管理。

2.1.new/delete操作內(nèi)置類型

new運算符

new運算符用來申請一塊連續(xù)的內(nèi)存,其格式如下:

new 數(shù)據(jù)類型 (初始化列表);

malloc()函數(shù)申請內(nèi)存時返回的是一個void*類型的指針,而new與malloc()不同,它分配一塊存儲空間并且指定了類型信息,并根據(jù)初始化列表中給出的值進(jìn)行初始化,是直接可以使用的內(nèi)存,這個過程稱之為new一個對象。 而且new動態(tài)創(chuàng)建對象時不必為該對象命名,直接指定數(shù)據(jù)類型即可。如果申請內(nèi)存成功,返回一個類型指針;如果申請內(nèi)存失敗,則返回NULL。

用new可以創(chuàng)建基本數(shù)據(jù)類型對象,也可以創(chuàng)建數(shù)組對象,其格式如下:

new 數(shù)據(jù)類型 [數(shù)組長度];

使用new創(chuàng)建數(shù)組時,后面可以加小括號(),但括號中不可以指定任何初始值,加小括號時由編譯器為其提供默認(rèn)初始值,而不加小括號時不提供任何初始值。例如:

int* pi=new int[10]();//pi所指向的數(shù)組中10個元素初始化為0
char* pc=new char[10];//pc所指向的數(shù)組中沒有提供初始值

C++雖然不允許定義長度為0的數(shù)組變量,但明確指出,調(diào)用new創(chuàng)建長度為0的數(shù)組是合法的,它返回有效的非零指針,但該指針不能進(jìn)行有效的解引用操作,因為它沒有指向任何元素,它主要的作用是用于比較運算。例如:

double *pd=new double[0];

delete運算符

用new運算符分配內(nèi)存,使用后要及時釋放以免造成內(nèi)存泄漏,C++提供了delete運算符來釋放new出來的內(nèi)存空間,其格式如下:

delete 指針名;

直接作用于指針就可以刪除由new創(chuàng)建的對象,釋放指針?biāo)赶虻膬?nèi)存空間。但在釋放數(shù)組對象時要在指針名前加上[ ],其格式如下:

delete [] 指針名;

如果缺失[ ],編譯器在編譯時不會報錯,但delete只能釋放部分空間,因此在程序運行時會出現(xiàn)內(nèi)存泄漏等問題。

int main()
{int* p1 = new int;//不會初始化:動態(tài)申請一個int類型的空間int* p3 = new int(10);//會初始化:申請一個int類型的空間,初始化為10int* p4 = new int[10];//申請10個int的數(shù)組,不會初始化int* p5 = new int[10]{ 1,2,3,4 };//會初始化delete p1;delete p3;delete [] p4;delete [] p5;//C語言版//int* p2 = (int*)malloc(sizeof(int));//if (p2 == nullptr)//{//	perror("malloc fail");//}return 0;
}

調(diào)試分析:

注意:

申請和釋放單個元素的空間,使用new和delete操作符;申請和釋放連續(xù)的空間,使用new[]和delete[],要匹配起來使用。

2.2.new/delete操作自定義類型

new/delete除了可以操作內(nèi)置類型,也可以操作自定義類型。

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}//注意:不加缺省值會報錯,提示:沒有合適的默認(rèn)構(gòu)造函數(shù)可用/*A(int a): _a(a){cout << "A():" << this << endl;}*/~A(){cout << "~A():" << this << endl;}private:int _a;
};
//
//匹配使用,不要交叉,否則結(jié)果是不確定的,malloc出來的就要用free釋放,new出來的就要用delete釋放,不要混淆了
int main()
{//new/delete 和 malloc/free 最大區(qū)別是 new/delete對于【自定義類型】除了開辟空間還會調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);//調(diào)用構(gòu)造函數(shù)free(p1);delete p2;//調(diào)用析構(gòu)函數(shù)// 內(nèi)置類型幾乎是一樣的int* p3 = (int*)malloc(sizeof(int)); // Cint* p4 = new int;free(p3);delete p4;A* p5 = (A*)malloc(sizeof(A) * 10);A* p6 = new A[10];//調(diào)用10次構(gòu)造函數(shù)free(p5);delete[] p6;//調(diào)用10次析構(gòu)函數(shù)return 0;
}

運行結(jié)果:

注意:

要匹配使用,不要交叉,否則結(jié)果是不確定的,malloc出來的就要用free釋放,new出來的就要用delete釋放,不要混淆。

三.operator new與operator delete函數(shù)

new和delete是用戶進(jìn)行動態(tài)內(nèi)存申請和釋放的操作符,operator new和operator delete是系統(tǒng)提供的全局函數(shù),new在底層調(diào)用operator new全局函數(shù)來申請空間,delete在底層通過operator delete全局函數(shù)來釋放空間。如下所示:

//operator new:該函數(shù)實際通過malloc來申請空間,當(dāng)malloc申請空間成功時直接返回;申請空間失敗,嘗試執(zhí)行空間不足應(yīng)對措施,如果該應(yīng)對措施用戶設(shè)置了,則繼續(xù)申請,否則拋異常。
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{// try to allocate size bytesvoid* p;while ((p = malloc(size)) == 0){if (_callnewh(size) == 0){// report no memory// 如果申請內(nèi)存失敗了,這里會拋出bad_alloc 類型異常static const std::bad_alloc nomem;_RAISE(nomem);}}return (p);
}//operator delete: 該函數(shù)最終是通過free來釋放空間的
void operator delete(void* pUserData)
{_CrtMemBlockHeader* pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData == NULL)return;_mlock(_HEAP_LOCK);  /* block other threads */__TRY/* get a pointer to memory block header */pHead = pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));_free_dbg(pUserData, pHead->nBlockUse);__FINALLY_munlock(_HEAP_LOCK);  /* release other threads */__END_TRY_FINALLYreturn;
}

案例:

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}//注意:不加缺省值會報錯,提示:沒有合適的默認(rèn)構(gòu)造函數(shù)可用/*A(int a): _a(a){cout << "A():" << this << endl;}*/~A(){cout << "~A():" << this << endl;}private:int _a;
};int main()
{A* a = new A(1);delete a;return 0;
}

反匯編分析:

小結(jié):

通過上述兩個全局函數(shù)的實現(xiàn)知道,operator new實際也是通過malloc來申請空間,如果malloc申請空間成功就直接返回,否則執(zhí)行用戶提供的空間不足應(yīng)對措施,如果用戶提供該措施就繼續(xù)申請,否則就拋異常。operator delete最終是通過free來釋放空間的。

提問:

既然operator new和operator delete這兩個全局函數(shù)是用malloc和free實現(xiàn)的,那我們是否可以用operator new和operator delete來實現(xiàn)malloc和free的功能??

答案:可以。

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}//注意:不加缺省值會報錯,提示:沒有合適的默認(rèn)構(gòu)造函數(shù)可用/*A(int a): _a(a){cout << "A():" << this << endl;}*/~A(){cout << "~A():" << this << endl;}private:int _a;
};int main()
{//內(nèi)置類型int* p1 = (int*)operator new(sizeof(int));int* p2 = new int;operator delete(p1);delete p2;//自定義類型A* p3 = (A*)operator new(sizeof(A));//不會調(diào)用構(gòu)造函數(shù)A* p4 = new A(1);operator delete(p3);//不會調(diào)用析構(gòu)函數(shù)delete p4;return 0;
}

四.new和delete的實現(xiàn)原理

內(nèi)置類型

如果申請的是內(nèi)置類型的空間,new和malloc,delete和free基本類似。不同的地方是:new/delete申請和釋放的是單個元素的空間,new[ ]和delete[ ]申請的是連續(xù)空間,而且new在申請空間失敗時會拋異常,malloc會返回NULL。

int main()
{//內(nèi)置類型//失敗了拋出異常//int* p1 = (int*)operator new(sizeof(int));int* p1 = new int;//失敗了返回空int* p2 = (int*)malloc(sizeof(int*));if (p2 == nullptr){perror("malloc fail");}return 0;
}

自定義類型

new的原理:

  1. 調(diào)用operator new函數(shù)申請空間;
  2. 在申請的空間上執(zhí)行構(gòu)造函數(shù),完成對象的構(gòu)造。

delete的原理:

  1. 在空間上執(zhí)行析構(gòu)函數(shù),完成對象中資源的清理工作;
  2. 調(diào)用operator delete函數(shù)釋放對象的空間。

new T[N]的原理:

  1. 調(diào)用operator new[]函數(shù),在operator new[]中實際調(diào)用operator new函數(shù)完成N個對象空間的申請;
  2. 在申請的空間上執(zhí)行N次構(gòu)造函數(shù)。

delete[]的原理:

  1. 在釋放的對象空間上執(zhí)行N次析構(gòu)函數(shù),完成N個對象中資源的清理;
  2. 調(diào)用operator delete[]釋放空間,實際在operator delete[]中調(diào)用operator delete來釋放空間。

案例一: 自定義類型

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}private:int _a;
};int main()
{//自定義類型//申請空間:operator new -> 封裝malloc//調(diào)用構(gòu)造函數(shù)A* p5 = new A;//先調(diào)用析構(gòu)函數(shù)//再operator delete p5指向的空間delete p5;//申請空間:operator new[] -> operator new -> 封裝malloc//調(diào)用10次構(gòu)造函數(shù)A* p6 = new A[10];//先調(diào)用10次析構(gòu)函數(shù)//再operator delete[] p6指向的空間delete[] p6;A* p9 = new A[10];//free(p9);//delete p9;//把自定義的析構(gòu)函數(shù)屏蔽掉,則不會調(diào)用析構(gòu)函數(shù),可以運行通過,此時的編譯器也不會去多開辟4個字節(jié)的空間來存放元素個數(shù)10delete[] p9;//vs編譯器會多開4個字節(jié)的空間存放個數(shù)10,return 0;
}

解析:

案例二:自定義類型不匹配問題

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}private:int _a;
};class Stack
{
public:Stack(){cout << "Stack()" << endl;_a = new int[4];_top = 0;_capacity = 4;}~Stack(){delete[] _a;_top = _capacity = 0;}private:int* _a;int _top;int _capacity;
};int main()
{//內(nèi)置類型不匹配通常不會報錯int* p7 = new int[10];free(p7);//自定義類型不匹配A* p8 = new A;//free(p8);//少調(diào)用析構(gòu)函數(shù),但由于不涉及內(nèi)存申請,通常不會報錯delete p8;Stack st;//st存放在棧上,為12字節(jié),其中存放了_a等,通過調(diào)用構(gòu)造函數(shù)為_a開辟了16字節(jié)的內(nèi)存空間,并指向了這塊空間Stack* pst = new Stack;//pst存放在棧上,為指針占4個字節(jié),new時會去堆上開辟12個字節(jié)的空間存放_a等,通過調(diào)用構(gòu)造函數(shù)為_a開辟了16字節(jié)的內(nèi)存空間,并指向了這塊空間//free(pst);//少調(diào)用析構(gòu)函數(shù),但由于涉及內(nèi)存申請,導(dǎo)致內(nèi)存泄漏,但不會報錯delete pst;//先調(diào)用析構(gòu)函數(shù)釋放_a所指向的內(nèi)存空間(16字節(jié)),再調(diào)用operator delete(pst)釋放new時在堆上開辟12個字節(jié)的空間//結(jié)論//由于 new/delete 底層實現(xiàn)機制有關(guān)聯(lián)交叉。不匹配使用時,可能有問題,可能沒問題,建議大家一定匹配使用return 0;
}

解析:

五.定位new表達(dá)式(placement-new)

定位new表達(dá)式是在已分配的原始內(nèi)存空間中調(diào)用構(gòu)造函數(shù)初始化一個對象。

使用格式:

new (place_address) type或者new (place_address) type(initializer-list)

注意:place_address必須是一個指針,initializer-list是類型的初始化列表。

使用場景:

定位new表達(dá)式在實際中一般是配合內(nèi)存池使用。因為內(nèi)存池分配出的內(nèi)存沒有初始化,所以如果是自定義類型的對象,需要使用new的定義表達(dá)式進(jìn)行顯示調(diào)構(gòu)造函數(shù)進(jìn)行初始化。

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}private:int _a;
};int main()
{A aa;//p1現(xiàn)在指向的只不過是與A對象相同大小的一段空間,還不能算是一個對象,因為構(gòu)造函數(shù)沒有執(zhí)行A* p1 = (A*)malloc(sizeof(A));if (p1 == nullptr){perror("malloc fail");}//對一塊已有空間初始化--定位new//new(p1)A;//注意:如果A類的構(gòu)造函數(shù)有參數(shù)時,此處需要傳參new(p1)A(1);p1->~A();free(p1);A* p2 = (A*)operator new(sizeof(A));new(p2)A(10);p2->~A();operator delete(p2);return 0;
}

六.malloc/free和new/delete的區(qū)別

malloc/free和new/delete的共同點是:它們都是從堆上申請空間,并且需要用戶手動釋放。不同的地方是:

  1. malloc和free是函數(shù),new和delete是操作符;
  2. malloc申請的空間不會初始化,new可以初始化;
  3. malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上空間的類型即可,如果是多個對象,[ ]中指定對象個數(shù)即可;
  4. malloc的返回值為void*,在使用時必須強轉(zhuǎn),new不需要,因為new后跟的是空間的類型;
  5. malloc申請空間失敗時,返回的是NULL,因此使用時必須判空,new不需要,但是new需要捕獲異常;
  6. 申請自定義類型對象時,malloc/free只會開辟空間,不會調(diào)用構(gòu)造函數(shù)與析構(gòu)函數(shù),而new在申請空間后會調(diào)用構(gòu)造函數(shù)完成對象的初始化,delete在釋放空間前會調(diào)用析構(gòu)函數(shù)完成空間中資源的清理。?

七.內(nèi)存泄漏

什么是內(nèi)存泄漏,內(nèi)存泄漏有什么危害?

什么是內(nèi)存泄漏:內(nèi)存泄漏指因為疏忽或錯誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。內(nèi)存泄漏并不是指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,因為設(shè)計錯誤,失去了對該段內(nèi)存的控制,因而造成了內(nèi)存的浪費。
內(nèi)存泄漏的危害:長期運行的程序出現(xiàn)內(nèi)存泄漏,影響很大,如操作系統(tǒng)、后臺服務(wù)等等,出現(xiàn)內(nèi)存泄漏會導(dǎo)致響應(yīng)越來越慢,最終卡死。

http://aloenet.com.cn/news/46745.html

相關(guān)文章:

  • 網(wǎng)站制作營銷型seo常用工具
  • 東莞網(wǎng)站制作十強seo 培訓(xùn)教程
  • 商務(wù)網(wǎng)站開發(fā)騰訊企點客服
  • 建設(shè)一個公司網(wǎng)站寧波網(wǎng)站推廣優(yōu)化公司怎么樣
  • 中國電力建設(shè)股份有限公司官方網(wǎng)站廣州百度關(guān)鍵詞搜索
  • 酒店微信網(wǎng)站建設(shè)云優(yōu)化seo軟件
  • 深圳網(wǎng)站制作hi0755營銷qq下載
  • 濟(jì)南 營銷型網(wǎng)站建設(shè)企業(yè)培訓(xùn)課程
  • 有經(jīng)驗的網(wǎng)站建設(shè)公司seo優(yōu)化服務(wù)是什么意思
  • h5網(wǎng)站設(shè)計欣賞免費網(wǎng)站安全軟件大全
  • 學(xué)校網(wǎng)站建設(shè)招標(biāo)方案百度知道首頁官網(wǎng)
  • 租用服務(wù)器建設(shè)網(wǎng)站費用win10優(yōu)化大師有用嗎
  • 德州做網(wǎng)站的競價托管服務(wù)多少錢
  • 無錫做公司網(wǎng)站的網(wǎng)絡(luò)搜索詞排名
  • 網(wǎng)站開發(fā)實用技術(shù)介紹南寧一站網(wǎng)網(wǎng)絡(luò)技術(shù)有限公司
  • 上海網(wǎng)站開發(fā)建優(yōu)秀的軟文廣告案例
  • 海淀區(qū)企業(yè)網(wǎng)站建設(shè)公司網(wǎng)站設(shè)計制作
  • 北京 順義 網(wǎng)站制作培訓(xùn)網(wǎng)站制作
  • 自制圖片肇慶網(wǎng)站快速排名優(yōu)化
  • wordpress映射新余seo
  • 視頻解析接口網(wǎng)站怎么做百度提交網(wǎng)站
  • 怎么自己做三個一網(wǎng)站一份完整的營銷策劃書
  • 做農(nóng)產(chǎn)品的網(wǎng)站北京優(yōu)化seo排名優(yōu)化
  • 國外銷售網(wǎng)站怎樣建設(shè)免費長尾詞挖掘工具
  • 麗水專業(yè)網(wǎng)站建設(shè)哪家好抖音seo優(yōu)化
  • wordpress.conf網(wǎng)站seo優(yōu)化免費
  • 有沒有給做淘寶網(wǎng)站的中國十大網(wǎng)站有哪些
  • 做網(wǎng)站需要什么部門批準(zhǔn)重慶seo優(yōu)化效果好
  • 濟(jì)寧做企業(yè)網(wǎng)站濟(jì)南網(wǎng)站優(yōu)化排名推廣
  • 在哪里做網(wǎng)站比較好十大廣告投放平臺