最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中動態(tài)內(nèi)存管理的實現(xiàn)

 更新時間:2025年09月08日 15:47:33   作者:祁同偉.  
本文主要介紹了C++中動態(tài)內(nèi)存管理的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

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

  1. 棧:非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等,棧是向下增長的。
  2. 內(nèi)存映射段是高效的I/O映射方式,用于裝載一個共享的動態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享共享內(nèi)存,做進程間通信。(Linux詳細講解)
  3. 堆:程序運行時動態(tài)內(nèi)存分配,堆是可以上增長的。
  4. 數(shù)據(jù)段、靜態(tài)區(qū):存儲全局數(shù)據(jù)和靜態(tài)數(shù)據(jù)。
  5. 代碼段、常量區(qū):可執(zhí)行的代碼/只讀常量。
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
    static int staticVar = 1;
    int localVar = 1;
    int num1[10] = { 1,2,3,4 };
}

globalVar、staticGlobalVar、staticVar在靜態(tài)區(qū)
localVar、num1在棧

void Test
{
    char char2[] = "abcd";
    const char* pChar3 = "abcd"; // 常量字符串,如果不加const則權(quán)限放大,報錯
    int* ptr1 = (int*)malloc(sizeof(int) * 4);
    int* ptr2 = (int*)calloc(4, sizeof(int));
    int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
    free(ptr1);
    free(ptr3);
}

char2、*char2、pChar3、ptr1在棧
*pChar3在常量區(qū)
*ptr1在堆

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

C主要靠malloc/calloc/realloc/free等函數(shù)手段完成
C++通過 new delete 操作符進行動態(tài)內(nèi)存管理

1. 內(nèi)置類型

內(nèi)置類型C&C++沒太大區(qū)別。
C++的 new delete 不用算多少字節(jié)、不用強轉(zhuǎn)

new、delete 申請和釋放的是單個元素的空間
new[ ]、delete[ ] 申請的是連續(xù)空間

int main()
{
    // C
    int* p1 = (int*)malloc(sizeof(int)); // 隨機值
    free(p1);

    // C++ 動態(tài)申請一個int類型的空間
    int* p2 = new int; // 隨機值
    delete p2;

    // C
    int* p3 = (int*)malloc(sizeof(int)*10); // 全是隨機值
    free(p3);

    // C++ 動態(tài)申請10個int類型的空間
    int* p4 = new int[10]; // 全是隨機值
    delete[] p4;

    // C++ 動態(tài)申請一個int類型的空間并初始化為10
    int* p5 = new int(10);
    delete p5;

    int* p6 = new int[10]{1,2,3}; // 其余是0
    delete[] p6;

    return 0;
}

2. 自定義類型

C:malloc 只是單純開空間,不初始化;free 不清理資源
C++:new 出來就調(diào)用構(gòu)造函數(shù)初始化;delete 調(diào)用析構(gòu)函數(shù)

struct ListNode
{
    int _val;
    struct ListNode* _next;

    ListNode(int x) // 構(gòu)造函數(shù)
        :_val(x)
        , _next(NULL)
    {}
};

struct ListNode* BuyListNode(int x)
{
    // 單純開空間
    struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
    // 檢查
    newnode->_next = NULL;
    newnode->_val = x;

    return newnode;
}

int main()
{
    struct ListNode* n1 = BuyListNode(1);
    struct ListNode* n2 = BuyListNode(2);
    struct ListNode* n3 = BuyListNode(3);

    // 開空間+調(diào)用構(gòu)造函數(shù)初始化
    ListNode* nn1 = new ListNode(1);
    ListNode* nn2 = new ListNode(2);
    ListNode* nn3 = new ListNode(3);

    return 0;
}
class A
{
public:
    A(int a = 0)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }

    ~A()
    {
        cout << "~A():" << this << endl;
    }

private:
    int _a;
};

int main()
{
	A* p1 = (A*)malloc(sizeof(A));
	A* p2 = new A(1);
	free(p1);
	delete p2;

	A* p5 = (A*)malloc(sizeof(A) * 10);
	A* p6 = new A[4];
	free(p5);
	delete[] p6;

	return 0;
}

p6 全初始化成 0,因為構(gòu)造函數(shù)給了缺省參數(shù)

如果沒有默認構(gòu)造函數(shù)

class A
{
public:
    A(int a)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }

    ~A()
    {
        cout << "~A():" << this << endl;
    }

private:
    int _a;
};

int main()
{
	// A* p6 = new A[4]; // 報錯:“A”: 沒有合適的默認構(gòu)造函數(shù)可用
    A* p6 = new A[4]{ 1,2,3,4 };
    A* p6 = new A[4]{ A(1),A(2),A(3),A(4) }; // 給4個匿名對象
	delete[] p6;
	return 0;
}

如果多個參數(shù)

class A
{
public:
    A(int a, int b)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }

    A(const A& aa)
        : _a(aa._a)
    {
        cout << "A(const A& aa):" << this << endl;
    }

    ~A()
    {
        cout << "~A():" << this << endl;
    }

private:
    int _a;
};

int main()
{
    A* p2 = new A(1, 1);
	delete p2;

    A* p6 = new A[4]{ A(1,1),A(2,2),A(3,3),A(4,4) };
	delete[] p6;

	return 0;
}

構(gòu)造+拷貝構(gòu)造-->優(yōu)化為直接構(gòu)造

此時,沒有默認構(gòu)造,必須傳4個匿名對象。如果給了缺省參數(shù),有了默認構(gòu)造,可以少傳

三. new delete 底層

operator new、operator delete 函數(shù):

他們不是運算符重載,是庫里的全局函數(shù)。他們不是給程序員用的,是給 new、delete用的

C語言處理失敗,返回錯誤碼。C語言喜歡用 malloc,申請失敗返回 0(NULL)
C++處理失敗,拋異常

C++源代碼中:
operator new 實際也是通過malloc來申請空間。若malloc申請空間成功就直接返回;否則執(zhí)行用戶提供的空間不足應(yīng)對措施,如果用戶提供該措施就繼續(xù)申請,否則就拋異常
operator delete 最終是通過free來釋放空間的(malloc、free只是隱藏起來了,不是沒用了)

new[ ]:
        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來釋放空間

用 Stack 理解

int main()
{
	// 申請一個堆上的棧對象
	Stack* p1 = new Stack;
	delete p1;

	return 0;
}

用 new 就不用加 if (NULL==_array) 這種檢查了。new 失敗拋異常,我們在所有 new 的地方 try catch捕獲就行

int main()
{
	try
	{
		// 申請一個堆上的棧對象
		Stack* p1 = new Stack;
		delete p1;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	return 0;
}

這里的 try catch 不僅能捕獲 main 函數(shù)里的;還能捕獲構(gòu)造函數(shù)里面的異常
只要是在范圍內(nèi),直接、間接調(diào)用的都可以捕獲

四. 定位 new 表達式(placement-new)

new 的其他操作

定位new表達式是對已有空間調(diào)用構(gòu)造函數(shù) 初始化一個對象

格式:new (指針) 類型new (指針) 類型(類型的初始化列表)

int main()
{
    // p1現(xiàn)在指向的只不過是與A對象相同大小的一段空間,還不能算是一個對象,因為構(gòu)造函數(shù)沒有執(zhí)行
    A* p1 = (A*)malloc(sizeof(A));
    // 顯示調(diào)用構(gòu)造函數(shù)
    new(p1)A; // 注意:如果A類的構(gòu)造函數(shù)有參數(shù)時,此處需要傳參 new(p1)A(1);

    // 顯示調(diào)用析構(gòu)函數(shù)
    p1->~A();
    free(p1);
    // 自定義類型的對象才能自動調(diào)用構(gòu)造、析構(gòu)函數(shù)。p1是內(nèi)置類型,必須顯示調(diào)用析構(gòu)

    return 0;
}

應(yīng)用場景:池化技術(shù):內(nèi)存池、線程池、連接池

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

需要頻繁申請和釋放內(nèi)存。new 是直接找堆,路徑長、麻煩
建池子,提前申請一大塊內(nèi)存放到池子里。要的時候直接找池子要,池子沒了再去找堆。效率高

五. 內(nèi)存泄露

http://www.fzitv.net/program/334321hr3.htm

到此這篇關(guān)于C++中動態(tài)內(nèi)存管理的實現(xiàn)的文章就介紹到這了,更多相關(guān)C++ 動態(tài)內(nèi)存管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++求所有頂點之間的最短路徑(用Floyd算法)

    C++求所有頂點之間的最短路徑(用Floyd算法)

    這篇文章主要為大家詳細介紹了C++求所有頂點之間的最短路徑,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言 TerminateProcess函數(shù)案例詳解

    C語言 TerminateProcess函數(shù)案例詳解

    這篇文章主要介紹了C語言 TerminateProcess函數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C/C++ memset方法的誤區(qū)

    C/C++ memset方法的誤區(qū)

    memset 作為對內(nèi)存初始化的函數(shù),還是有不少坑和誤區(qū)的,今天就來對這個函數(shù)作一個總結(jié)。避免后期使用不當(dāng)踩入坑,需要的朋友可以參考下
    2021-04-04
  • 深入VC回調(diào)函數(shù)的使用詳解

    深入VC回調(diào)函數(shù)的使用詳解

    本篇文章是對VC回調(diào)函數(shù)的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++線程鎖的使用

    C++線程鎖的使用

    C++提供了多種鎖機制,本文主要介紹了C++線程鎖的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • c語言打開文件函數(shù)使用方法

    c語言打開文件函數(shù)使用方法

    這篇文章主要介紹了c語言打開文件函數(shù)使用方法,需要的朋友可以參考下
    2014-02-02
  • 關(guān)于C++一些特性的探究

    關(guān)于C++一些特性的探究

    下面小編就為大家?guī)硪黄P(guān)于C++一些特性的探究。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • C++lambda表達式使用介紹

    C++lambda表達式使用介紹

    Lambda 表達式(lambda expression)是一個匿名函數(shù),Lambda表達式基于數(shù)學(xué)中的λ演算得名。本文就來為大家詳細講講C++中Lambda表達式的使用,需要的可以參考一下
    2022-08-08
  • QT中刪除信號于槽的連接的實現(xiàn)

    QT中刪除信號于槽的連接的實現(xiàn)

    本文主要介紹了QT中刪除信號于槽的連接的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C++ list-map鏈表與映射表的簡單使用

    C++ list-map鏈表與映射表的簡單使用

    本文主要介紹了C++ list-map鏈表與映射表的簡單使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05

最新評論

安义县| 安岳县| 依安县| 商丘市| 孟连| 呼伦贝尔市| 台湾省| 句容市| 静乐县| 察雅县| 夏津县| 静海县| 永泰县| 麻城市| 雅安市| 万全县| 菏泽市| 柘城县| 渭南市| 会宁县| 惠东县| 宜宾县| 六枝特区| 双牌县| 京山县| 武威市| 蒲城县| 抚顺市| 明光市| 图们市| 财经| 金沙县| 堆龙德庆县| 商城县| 江门市| 江都市| 菏泽市| 张家口市| 德安县| 南城县| 水城县|