国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象

這篇具有很好參考價值的文章主要介紹了[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象,C++,c++,開發(fā)語言

?

目錄

1、C/C++內存分布

2.、C語言中動態(tài)內存管理方式:malloc、calloc、realloc

3、C++內存管理方式

3.1 new/delete操作內置類型

3.2 new和delete操作自定義類型

3.3 malloc與new的異常處理機制

4、operator new與operator delete函數

4.1 operator new與operator delete函數

4.1.1 operator new源碼

4.1.2 operator delete源碼

5、new和delete的實現原理

5.1 內置類型

5.2 自定義類型

5.2.1 new的原理

5.2.2 delete的原理

5.2.3new T[N]的原理

5.2.4 delete[]的原理

6、定位new表達式(了解)

7、malloc/free和new/delete的區(qū)別

7.1 malloc/free和new/delete 相同點

7.2 malloc/free和new/delete 不相同點


1、C/C++內存分布

我們先來了解一下C/C++內存分配的幾個區(qū)域,以下面的代碼為例來看:

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
    static int staticVar = 1;
    int localVar = 1;
    int num1[10] = { 1, 2, 3, 4 };
    char char2[] = "abcd";
    const char* pChar3 = "abcd";
    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);
}

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象,C++,c++,開發(fā)語言

說明:

1. 棧又叫堆棧--非靜態(tài)局部變量/函數參數/返回值等等,棧是向下增長的。
2. 內存映射段是高效的I/O映射方式,用于裝載一個共享的動態(tài)內存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享共享內存,做進程間通信。

3. 用于程序運行時動態(tài)內存分配,堆是可以上增長的。
4. 數據段/靜態(tài)區(qū)--存儲全局數據和靜態(tài)數據。
5. 代碼段/常量區(qū)--可執(zhí)行的代碼/只讀常量。

2.、C語言中動態(tài)內存管理方式:malloc、calloc、realloc

malloc:向內存申請一塊空間,成功的話返回內存塊的指針,失敗返回空指針(NULL);

calloc:向內存申請一塊空間,并逐字節(jié)初始化為0,成功的話返回內存塊的指針,失敗返回空指針(NULL);

realloc:調整動態(tài)開辟的內存大小。

我們以代碼舉例來看看:

int mian()
{
	int* p1 = (int*)malloc(sizeof(int));

	int* p2 = (int*)realloc(p1, sizeof(int) * 10);// 擴容,若是異地擴容realloc會將p1的內容
	free(p2);									  // 拷貝到p2開出的內存中并釋放掉p1的內存

	int* p3 = (int*)calloc(1, sizeof(int));// 開辟四個字節(jié)空間,并初始化為 1
	free(p3);
	
	return 0;
}

3、C++內存管理方式

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

3.1 new/delete操作內置類型

int main()
{
	// 管理對象
	// 動態(tài)開辟一個int類型的空間
	int* p1 = new int;
	// 動態(tài)開辟一個int類型的空間,并初始化為1
	int* p2 = new int(1);

	//管理對象數組
	// 動態(tài)開辟一個int類型的數組
	int* p3 = new int[10];
	// 動態(tài)開辟一個int類型的數組,并初始化
	int* p4 = new int[10]{};// 不寫初始化值,默認初始化為 0
	// 動態(tài)開辟一個int類型的數組,并初始化
	int* p5 = new int[10]{ 1,2,3 };// 前三個分別初始化為1 2 3,后面默認初始化為 0

	//釋放開辟的內存
	delete p1;
	delete p2;
	delete[] p3;// 對應釋放數組加[]
	delete[] p4;
	delete[] p5;

	return 0;
}

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象,C++,c++,開發(fā)語言

我們啟動監(jiān)視窗口看看結果:

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象,C++,c++,開發(fā)語言

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

3.2 new和delete操作自定義類型

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

int main()
{
	A* a1 = (A*)malloc(sizeof(A));

	A* a2 = new A;

	free(a1);

	delete(a2);

	return 0;
}

我們來看看malloc、new開辟動態(tài)內存 與 free、delete釋放內存。

我們先來看結果:

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象,C++,c++,開發(fā)語言

這里分別自動調用了一次構造函數與析構函數。這里到底是誰調用的呢?

對于C語言來說,是不存在構造函數的,因此C語言設計的malloc是不會自動調用構造函數的,free也是不會調用析構函數,但是對于C++來講,是面向對象的,new與delete會在開辟與釋放內存時調用構造函數與析構函數。

注意:在申請自定義類型的空間時,new會調用構造函數,delete會調用析構函數,而malloc與free不會。

3.3 malloc與new的異常處理機制

int main()
{
	int* p1 = (int*)malloc(1024 * 1024 * 1024);
	cout << p1 << endl;

	int* p2 = (int*)malloc(1024 * 1024 * 1024);
	cout << p2 << endl;

	try
	{
		char* p3 = new char[0x7fffffff];
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	return 0;
}

[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象,C++,c++,開發(fā)語言

當malloc失敗時返回空指針,而new失敗了會拋異常。
new失敗后,直接會跳到異常捕獲語句,不執(zhí)行new后面的代碼,如果我們不捕獲異常程序就會終止掉。異常的捕獲只會在try、catch里面,不在里面就不會捕獲異常。

4、operator new與operator delete函數

4.1 operator new與operator delete函數

C++的標準庫里提供了operator new與operator delete函數,但是這兩個函數不是重載,只是名字像重載,是系統(tǒng)提供的兩個全局函數,new在底層調用operator new全局函數來申請空間,delete在底層通過operator delete全局函數來釋放空間。

我們來分別看看源碼:

4.1.1 operator new源碼

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
    // try to allocate size bytes
    void *p;
    while ((p = malloc(size)) == 0)
    if (_callnewh(size) == 0)
    {
        // report no memory
        // 如果申請內存失敗了,這里會拋出bad_alloc 類型異常
        static const std::bad_alloc nomem;
        _RAISE(nomem);
    }
    return (p);
}

operator new里封裝了malloc,失敗了會拋異常,

4.1.2 operator delete源碼

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_FINALLY
    return;
}

/*
free的實現
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)

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

5、new和delete的實現原理

5.1 內置類型

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

5.2 自定義類型

5.2.1 new的原理

1. 調用operator new函數申請空間
2. 在申請的空間上執(zhí)行構造函數,完成對象的構造

5.2.2 delete的原理

1. 在空間上執(zhí)行析構函數,完成對象中資源的清理工作
2. 調用operator delete函數釋放對象的空間

5.2.3new T[N]的原理

1. 調用operator new[]函數,在operator new[]中實際調用operator new函數完成N個對象空間的申請
2. 在申請的空間上執(zhí)行N次構造函數

5.2.4 delete[]的原理

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

6、定位new表達式(了解)

定位new表達式是在已分配的原始內存空間中調用構造函數初始化一個對象。
使用格式:
new (place_address) type或者new (place_address) type(initializer-list)
place_address必須是一個指針,initializer-list是類型的初始化列表

使用場景:

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

class A
{
public:
    A(int a = 0)
    : _a(a)
    {
    cout << "A():" << this << endl;
    }
    ~A()
    {
    cout << "~A():" << this << endl;
    }
private:
	int _a;
};
int main()
{
    // p1現在指向的只不過是與A對象相同大小的一段空間,還不能算是一個對象,因為構造函數沒
    有執(zhí)行
    A* p1 = (A*)malloc(sizeof(A));
    new(p1)A; // 顯示調用構造函數 注意:如果A類的構造函數有參數時,此處需要傳參
    p1->~A();
    free(p1);

    A* p2 = (A*)operator new(sizeof(A));
    new(p2)A(10);// 顯示調用構造函數
    p2->~A();
    operator delete(p2);
    
    return 0;
}

7、malloc/free和new/delete的區(qū)別

7.1 malloc/free和new/delete 相同點

都是從堆上申請空間,并且需要用戶手動釋放

7.2 malloc/free和new/delete 不相同點

1. malloc和free是函數,new和delete是操作符
2. malloc申請的空間不會初始化,new可以初始化
3. malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上空間的類型即可,如果是多個對象,[]中指定對象個數即可
4. malloc的返回值為void*, 在使用時必須強轉,new不需要,因為new后跟的是空間的類型
5. malloc申請空間失敗時,返回的是NULL,因此使用時必須判空,new不需要,但是new需要捕獲異常
6. 申請自定義類型對象時,malloc/free只會開辟空間,不會調用構造函數與析構函數,而new在申請空間后會調用構造函數完成對象的初始化,delete在釋放空間前會調用析構函數完成空間中資源的清理文章來源地址http://www.zghlxwxcb.cn/news/detail-645426.html

到了這里,關于[C++] 一篇帶你了解C++中動態(tài)內存管理,new讓大家都有對象的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【數據結構】一篇帶你徹底了解棧

    【數據結構】一篇帶你徹底了解棧

    棧:一種線性數據結構,其只允許在固定的一端進行插入和刪除元素操作。進行數據插入和刪除操作的一端稱為棧頂 (Top), 另一端稱為棧底 [Bottom]。棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。即最后進入的元素最先被訪問。 壓棧:棧的插入操作叫做進棧/壓棧

    2024年02月05日
    瀏覽(26)
  • [Linux 基礎] 一篇帶你了解linux權限問題

    [Linux 基礎] 一篇帶你了解linux權限問題

    Linux下有兩種用戶:超級用戶(root)、普通用戶。 超級用戶:可以再linux系統(tǒng)下做任何事情,不受限制 普通用戶:在linux下做有限的事情。 超級用戶的命令提示符是“#”,普通用戶的命令提示符是“ $ ” 命令: su [用戶名] 功能: 切換用戶。 例如,要從root用戶切換到普通用

    2024年02月08日
    瀏覽(21)
  • 【Mysql】一篇帶你了解數據定義,操作和查詢語言

    【Mysql】一篇帶你了解數據定義,操作和查詢語言

    目錄 數據定義語言DDL(Data Definition Language) 一.對數據庫的操作 二.對數據表的操作 數據操作語言DML(Data Manipulation Language) 一.添加 insert into 二.刪除? delete 三.修改? update 數據查詢語言DQL(Data Query Language) 一.查詢 select 二. 1.between ... and ...(在....之間) 2.in, exists

    2024年02月12日
    瀏覽(22)
  • C語言學習系列-->一篇帶你看懂內存函數

    C語言學習系列-->一篇帶你看懂內存函數

    上篇文章學習了C語言字符串函數,只是對字符串進行操作 本節(jié),小編整理了一下C語言中的內存函數,對內存進行操作,只針對會內存塊,不針對數據 memcpy是對內存拷貝 拷貝的可能是字符串,也可能是整型數組 所以使用 void* 將source拷貝到destination,指定字節(jié)數為num code arr

    2024年02月09日
    瀏覽(21)
  • [數據結構 -- 手撕排序第二篇] 一篇帶你詳細了解希爾排序

    [數據結構 -- 手撕排序第二篇] 一篇帶你詳細了解希爾排序

    目錄 1、常見排序算法 1.1 插入排序基本思想 2、希爾排序 2.1 希爾排序( 縮小增量排序 ) 2.1.1 預排序階段 2.1.2 插入排序階段 2.2 單趟希爾排序 2.2.1 思路分析 2.2.2 代碼實現 3、希爾排序代碼實現 4、希爾排序時間復雜度 5、希爾排序與插入排序效率對比 6、希爾排序特性總結 直接

    2024年02月13日
    瀏覽(28)
  • 一文帶你了解動態(tài)內存管理

    一文帶你了解動態(tài)內存管理

    目錄 動態(tài)內存存在的意義 動態(tài)內存函數的介紹 malloc和free calloc realloc 常見的動態(tài)內存錯誤 對NULL指針解引用操作 對動態(tài)開辟的空間的越界訪問 對非動態(tài)開辟內存使用free釋放 使用free釋放一塊動態(tài)開辟內存的一部分 對同一塊內存多次釋放 動態(tài)開辟內存忘記釋放 經典的筆試題

    2024年02月16日
    瀏覽(17)
  • C++ || C/C++內存管理 | C++動態(tài)內存管理方式 | operator new/delete函數 | new和delete實現原理 | 定位new表達式 | 內存泄漏

    C++ || C/C++內存管理 | C++動態(tài)內存管理方式 | operator new/delete函數 | new和delete實現原理 | 定位new表達式 | 內存泄漏

    C/C++中程序內存區(qū)域大致劃分六個部分: 內核空間 (用戶代碼不能讀寫)、 棧 (向下增長)、 內存映射段 (文件映射、動態(tài)庫、匿名映射)、 堆 (向上增長)、 數據段 (全局數據、靜態(tài)數據)、 代碼段 (可執(zhí)行代碼、只讀常量)。 各自內存區(qū)域功能 棧 ,又叫做堆棧

    2024年02月21日
    瀏覽(23)
  • C++與C語言動態(tài)內存管理的不同 new與malloc

    ? 目錄 1.C語言動態(tài)內存管理方式 2.C++中動態(tài)內存管理 2.1 new和delete操作內置類型 2.2 new和delete操作自定類型 2.3 為什么delete要帶[ ]? 3.new申請空間失敗 4.operator new 與 operator delete 函數 5.new與delete的是實現原理 5.1 內置類型 5.2 自定義類型 6.定位new表達式(了解即可) 7.malloc/free和

    2024年02月08日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包