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

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

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

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

??專欄導(dǎo)讀

??作者簡介:花想云,在讀本科生一枚,致力于 C/C++、Linux 學(xué)習(xí)。

??本文收錄于 C++系列,本專欄主要內(nèi)容為 C++ 初階、C++ 進階、STL 詳解等,專為大學(xué)生打造全套 C++ 學(xué)習(xí)教程,持續(xù)更新!

??相關(guān)專欄推薦:C語言初階系列C語言進階系列 、數(shù)據(jù)結(jié)構(gòu)與算法

??文章導(dǎo)讀

本章我們將學(xué)習(xí)C++的內(nèi)存分配動態(tài)內(nèi)存管理。理解new/delete的用法與實現(xiàn)的原理,并簡單了解定位new表達式

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

在C語言階段,我們已經(jīng)學(xué)習(xí)過內(nèi)存分布,認識了什么是堆、堆棧、靜態(tài)區(qū)、常量區(qū)等。如下圖:
C++——內(nèi)存分配與動態(tài)內(nèi)存管理
我們再次認識一下這幾個區(qū)域:

  • :又叫堆棧,主要存放非靜態(tài)局部變量、函數(shù)參數(shù)、返回值等等,棧是向下增長的;
  • 內(nèi)存映射段:是高效的I/O映射方式,用于裝載一個共享的動態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享共享內(nèi)存,做進程間通信。(Linux系列文章中有講解);
  • :用于程序運行時動態(tài)內(nèi)存分配,堆是可以上增長的;
  • 數(shù)據(jù)段:存儲全局數(shù)據(jù)和靜態(tài)數(shù)據(jù);
  • 代碼段:存儲可執(zhí)行的代碼與只讀常量;

??牛刀小試

我們可以通過以下測試例題來檢驗自己是否還清晰的記得C語言內(nèi)存分配的知識。

??測試例題

#include<stdio.h>
#include<stdlib.h>
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);
}
  1. 選擇題:
    選項: A.棧 B.堆 C.數(shù)據(jù)段(靜態(tài)區(qū)) D.代碼段(常量區(qū))
    globalVar在哪里?____ staticGlobalVar在哪里?____
    staticVar在哪里?____ localVar在哪里?____
    num1在哪里?____

    char2在哪里?____ *char2在哪里?___
    pChar3在哪里?____ *pChar3在哪里?____
    ptr1在哪里?____ *ptr1在哪里?____

  2. 填空題:
    sizeof(num1) = ____; sizeof(char2) = ____;
    strlen(char2) = ____; sizeof(pChar3) = ____;
    strlen(pChar3) = ____;sizeof(ptr1) = ____;

??答案
從左至右,從上至下給出:

CCCAA AAADAB 40 5 4 4/8 4 4/8

??C語言動態(tài)內(nèi)存管理

C語言動態(tài)內(nèi)存管理在我之前的文章中已經(jīng)詳細介紹過,鏈接如下:

  • C語言動態(tài)內(nèi)存管理與柔性數(shù)組

??C++動態(tài)內(nèi)存管理

C++在C語言的基礎(chǔ)上引進了新的動態(tài)內(nèi)存管理的方式——通過newdelete操作符進行動態(tài)內(nèi)存管理。

??對于內(nèi)置類型

對于內(nèi)置類型。new/deletemalloc/free幾乎是一樣的。

  • 動態(tài)申請一個int類型的空間;
	//int* p1 = (int*)malloc(sizeof(int)); //C
	int* p1 = new int;  //C++
  • 動態(tài)申請一個int類型的空間并初始化為10;
	int* p2 = new int(10);
	cout << *p2 << endl;

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

  • 動態(tài)申請10int類型的空間;
	int* p3 = new int[10];
  • 釋放空間
	//free(p1) //C
	//釋放單個元素的空間
	delete p1;
	delete p2;
	//釋放多個元素的空間
	delete[] p3;

??對于自定義類型

對于自定義類型,new/deletemalloc/free的最大區(qū)別是 new/delete對于自定義類型除了申請/釋放空間還會調(diào)用對應(yīng)的構(gòu)造函數(shù)析構(gòu)函數(shù)

class A
{
public:
	A()
	{
		cout << "A()" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
  • malloc與free
	A* p4 = (A*)malloc(sizeof(A));
	free(p4);
  • new與delete
	A* p5 = new A;
	delete p5;

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

??operator new與operator delete函數(shù)

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

??那么operator new與operator delete又是什么呢?

  • operator new其實是對malloc進行封裝后的產(chǎn)物;

之前我們使用malloc函數(shù)申請空間時,有非常重要的一點就是要對malloc申請的結(jié)果做檢查。如果malloc申請失敗會返回空指針。

??示例1

	int* a = (int*)malloc(sizeof(int));
	if (a == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

每次都要對返回值進行檢查,未免感到有點麻煩。在C++中,系統(tǒng)通過對malloc申請與檢查的工作進行封裝推出了operator new函數(shù)。當operator new申請空間失敗時,會通過拋異常(之后會將)的方式告訴用戶。

??示例2

	// 失敗了拋異常
	int* p1 = (int*)operator new(sizeof(int*));
  • operator delete作用與free相同;

??示例3

	int* p1 = (int*)operator new(sizeof(int*));
	operator delete(p1);

??new與delete的實現(xiàn)原理

??對于內(nèi)置類型

如果申請的是內(nèi)置類型的空間,new/mallocdelete/free基本類似,不同的地方是:

  • new/delete申請和釋放的是單個元素的空間,new[]delete[]申請的是連續(xù)空間;
  • new在申請空間失敗時會拋異常,malloc會返回NULL

??對于自定義類型

??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[]的原理
3. 在釋放的對象空間上執(zhí)行N次析構(gòu)函數(shù),完成N個對象中資源的清理;
4. 調(diào)用operator delete[]釋放空間,實際在operator delete[]中調(diào)用operator delete來釋放空間;

??對于調(diào)用析構(gòu)函數(shù)的理解

有的小伙伴可能并不清楚為什么要執(zhí)行析構(gòu)函數(shù)再執(zhí)行operator delete函數(shù),請思考一下,二者的操作對象是同一個空間嗎?

答案:

  • 析構(gòu)函數(shù)對象調(diào)用的,目的是清理對象內(nèi)部申請的資源(例如:動態(tài)開辟的數(shù)組、自定義類型的變量等);
  • operator delete是用來釋放存儲對象所在的空間。

通俗的理解就是:我申請了一塊空間A,并將A的地址交給指針變量P保存,A里面存儲了一個對象。但是對象內(nèi)部又申請了一塊空間B,B里面存儲了一些其它的數(shù)據(jù)。當我們delete p時,不能直接釋放A,因為A里面存儲的對象又申請了一塊空間B,我們得首先釋放B,不然B就無法釋放了。釋放B需要對象來調(diào)用它的析構(gòu)函數(shù),B成功的釋放了,接下來釋放A,調(diào)用operator delete來釋放A。

??示例

定義一個類:

class stack
{
public:
	stack()
		:_size(0),
		_capacity(0)
	{
		_a = new int[10];
		cout << "stack()" << endl;
	}
	~stack()
	{
		cout << "~stack()" << endl;
	}
private:
	int* _a;
	int _size;
	int _capacity;
};

new一個對象并釋放:

void Test()
{
	stack* ps = new stack;
	delete ps;
}

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

??定位new表達式

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

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

??示例

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

void Test5()
{
	A* p1 = (A*)malloc(sizeof(A));// p1現(xiàn)在指向的只不過是與A對象相同大小的一段空間,還不能算是一個對象,因為構(gòu)造函數(shù)沒有執(zhí)行
	new(p1)A; //注意:如果A的構(gòu)造函數(shù)有參數(shù)時需要傳參new(p1)(參數(shù)列表)
	p1->~A();
	free(p1);


	A* p2 = (A*)operator new(sizeof(A));
	new(p2)A(10);
	p2->~A();
	operator delete(p2);
}

??總結(jié)

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

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

  1. mallocfree函數(shù),newdelete操作符;
  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ù)完成空間中資源的清理;

C++——內(nèi)存分配與動態(tài)內(nèi)存管理

點擊下方個人名片,可添加博主的個人QQ,交流會更方便哦~
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓文章來源地址http://www.zghlxwxcb.cn/news/detail-416691.html

到了這里,關(guān)于C++——內(nèi)存分配與動態(tài)內(nèi)存管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • c語言:通訊錄管理系統(tǒng)(動態(tài)分配內(nèi)存版)

    c語言:通訊錄管理系統(tǒng)(動態(tài)分配內(nèi)存版)

    前言: 本通訊錄管理系統(tǒng)一共三個版本,除此文章以外還有如下倆個版本,大家可以根據(jù)需求自?。?基礎(chǔ)增刪查改功能版本 :c語言:通訊錄管理系統(tǒng)(增刪查改)_luming.02的博客-CSDN博客 文件保存版本 :c語言:通訊錄管理系統(tǒng)(文件版本)-CSDN博客 ????????本文是在基

    2024年02月08日
    瀏覽(104)
  • day42:C++ day2,C++對C的補充(引用、動態(tài)內(nèi)存分配與回收、函數(shù)擴充以及結(jié)構(gòu)體擴充)

    面試題小結(jié): 1、指針與引用的區(qū)別? (1)指針指向的是變量的地址,而引用是指向變量本身; (2)指針可以有多級指針,而引用只有一級引用; (3)指針可以不初始化,但是引用必須初始化; (4)指針可以改變指向,但是引用初始化后就不能更改對象; (5)指針用

    2024年02月09日
    瀏覽(14)
  • C++動態(tài)內(nèi)存管理+模板

    C++動態(tài)內(nèi)存管理+模板

    ??博主個人主頁:不是笨小孩?? ?專欄分類:數(shù)據(jù)結(jié)構(gòu)與算法?? C++?? 刷題專欄?? C語言?? ??代碼倉庫:笨小孩的代碼庫?? ?社區(qū):不是笨小孩?? ??歡迎大家三連關(guān)注,一起學(xué)習(xí),一起進步!!?? C語言內(nèi)存管理方式在C++中可以繼續(xù)使用,但有些地方就無能為力,而且使

    2024年02月09日
    瀏覽(28)
  • 【C++初階】動態(tài)內(nèi)存管理

    【C++初階】動態(tài)內(nèi)存管理

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

    2024年02月06日
    瀏覽(22)
  • 【C++】——動態(tài)內(nèi)存管理

    【C++】——動態(tài)內(nèi)存管理

    ? 目錄 ??導(dǎo)讀 ??C/C++內(nèi)存分布? ??C++內(nèi)存管理方式? ??new/delete操作內(nèi)置類型? ??new和delete的使用方法 ??operator new與operator delete函數(shù) ??new和delete的實現(xiàn)原理 ??內(nèi)置類型 ??自定義類型 ??定位new表達式? ??使用格式 ??malloc/free和new/delete的區(qū)別 ??作者簡介: 日出等日

    2024年02月07日
    瀏覽(22)
  • C++中內(nèi)存的動態(tài)管理

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

    我們在C語言中了解到可以在棧區(qū)動態(tài)開辟空間,并且用完要進行釋放,防止內(nèi)存泄漏。 C++中也有可以進行動態(tài)開辟空間和釋放空間的操作符 new ?、 delete, 雖然C++中也可以用malloc、calloc、realloc、free函數(shù),但是C++中引入了類,而類中又有構(gòu)造函數(shù)和析構(gòu)函數(shù),在實例化對象時

    2024年02月14日
    瀏覽(29)
  • 【C/C++】靜態(tài)內(nèi)存分配與動態(tài)內(nèi)存分配

    1.1 - 定義概述 內(nèi)存分配 (Memory Allocation) 是指為計算機程序或服務(wù)分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個過程。通常在程序執(zhí)行前或執(zhí)行時完成內(nèi)存分配。 1.2 - 分類概述 存在兩種類型的內(nèi)存分配: 編譯時內(nèi)存分配或靜態(tài)內(nèi)存分配 (Compile-time or Static Memory Allocation) 運行時內(nèi)存

    2024年02月11日
    瀏覽(24)
  • 動態(tài)分配內(nèi)存與釋放

    動態(tài)分配內(nèi)存與釋放

    1.malloc malloc()可以找到一個大小合適的塊。 內(nèi)存是匿名的,也就是說,malloc()分配了內(nèi)存,但沒有為它指定名字。 格式如下: double*ptd; ptd=(double*)malloc(30*sizeof(double)); ps:ptd可以看成是一個數(shù)組。 malloc()可能分配不到所需的內(nèi)存。在這種情況下,該函數(shù)返回空指針。

    2024年01月17日
    瀏覽(30)
  • 用指針實現(xiàn)內(nèi)存動態(tài)分配

    導(dǎo)引 :已知:變量在使用前必須被定義且安排好存儲空間。且變量有這么一些分類:全局變量、靜態(tài)局部變量【它們的儲存一般是在編譯時確定,在程序開始執(zhí)行前完成?!孔詣幼兞俊驹趫?zhí)行進入變量定義所在的復(fù)合語句時為它們分配存儲,變量的大小也是靜態(tài)確定的。臨時

    2023年04月09日
    瀏覽(28)
  • 內(nèi)存動態(tài)分區(qū)分配算法

    內(nèi)存動態(tài)分區(qū)分配算法

    所謂動態(tài)分區(qū)分配,就是指 內(nèi)存在初始時不會劃分區(qū)域,而是會在進程裝入時,根據(jù)所要裝入的進程大小動態(tài)地對內(nèi)存空間進行劃分,以提高內(nèi)存空間利用率,降低碎片的大小 動態(tài)分區(qū)分配算法有以下四種: 1. 首次適應(yīng)算法(First Fit) 空閑分區(qū)以 地址遞增的次序鏈接 。分

    2024年02月11日
    瀏覽(27)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包