C++學習第五天(內存管理)

1、內存分布

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);
}

下面有幾個問題:

  • globalvar存放在哪里? 答:數據段
  • staticGlobalVal存放在哪里?答:數據段
  • staticVar存放在哪里? 答:數據段
  • localVar存放在哪里? 答:棧
  • num1存放在哪里? 答:棧
  • char2存放在哪里? 答:棧
  • *char2存放在哪里? 答:棧
  • pChar3存放在哪里? 答:棧
  • *pChar3存放在哪里? 答:代碼段
  • ptr1存放在哪里? 答:棧
  • *ptr1存放在哪里? 答:堆

為什么存放在這些不同的位置呢?

C++/C內存分配有不同的位置

又叫堆棧:非靜態局部變量/函數參數/返回值等等,棧是向下增長的
內存映射段:這是高效的I/O映射方式,用于裝載一個動態內存庫。用戶可以使用系統接口創建共享內存,做進程間通信
:用于程序運行時動態內存分配,堆是可以向上增長的
數據段:存儲全局數據和靜態數據
代碼段:可執行代碼/只讀常量

2、C語言中動態內存管理方式:malloc/calloc/realloc/free

malloc:malloc有一個參數,在內存的動態存儲區中分配一塊長度為size字節的連續區域,參數size為需要的內存空間的長度,返回該區域的首地址

calloc:與malloc是相似的,只不過有兩個參數,參數一和參數二之積為所需開辟的內存空間的大小,而且這個會將開辟的空間的每一位都初始化為0

realloc:這個可以給以及分配地址的指針重新分配空間

3、C++內存管理方式

C++有了相對于C不同的內存管理方式;通過new和delete操作符來進行動態內存管理

new/delete操作內置類型

void Test()
{//動態申請一個int類的空間int* ptr4 = new int;//動態申請一個int類型的空間并且初始化為10int* ptr5 = new int(10);//動態申請10個int類型的空間int* ptr6 = new int[10];//動態申請10個int類型的空間并且初始化int* ptr7 = new int[10] {10, 9, 8, 7, 6, 5};//上面的初始化剩余沒被初始化的會被初始化0delete[] ptr6;
}

【Attention】申請和釋放單個元素的空間,使用new和delete操作符,申請和釋放連續的空間,使用new[]和delete[],注意要匹配使用

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()
{//new/delete 和 malloc/free 最大的區別是new/delete對于[自定義類型]除了開空間還會調用構造函數和析構函數A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);free(p1);delete p2;//內置類型幾乎是一樣的int* p3 = (int*)malloc(sizeof(int));int* p4 = new int;free(p3);delete p4;A* p5 = (A*)malloc(sizeof(A) * 10);A* p6 = new A[10];free(p5);delete[] p6;return 0;
}

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

4、operator new 與 operator delete函數(重點)

operator new 和 operator delete 函數

new和delete是用戶進行動態內存申請和釋放的操作符,operator new 和 operator delete 是系統提供的全局函數,new在底層調用operator new全局函數來申請空間,delete在底層通過operator delete全局函數來釋放空間?

int main()
{Stack* ps2 = (Stack*)operator new (sizeof(Stack));operator delete(ps2);Stack* ps1 = (Stack*)malloc(sizeof(Stack));assert(ps1);free(ps1);
}

operator new實際是通過malloc來申請空間,如果malloc申請空間成功則直接返回,否則執行用戶提供的空間不足應對措施,如果用戶提供該措施就繼續申請,否則就拋異常。operator delete最終就是通過free來申請空間的

5、new和delete的實現原理

內置類型

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

自定義類型

  • new的原理:1、調用operator new函數申請空間? ?2、在申請的空間上執行構造函數,完成對對象的構造
  • delete的原理:1、在空間上執行析構函數,完成對象中資源的清理工作? 2、調用operator delete函數釋放對象的空間
  • new T[N]的原理:1、調用operator new[]函數,在operator new[]中實際調用operator new函數完成N個對象空間的申請? 2、在申請的空間上執行N次構造函數
  • delete[]的原理:1、在釋放的對象空間上執行N次析構函數,完成對N個對象中資源的清理? 2、調用operator delete[]釋放空間,實際在operator delete[]中調用operator delete來釋放空間

6、定位new表達式(placement-new)

定位new表達式是在已分配的原始內存空間中調用構造函數初始化一個對象

使用格式:

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

place_address必須是一個指針,initializer-list是典型的初始化列表

class A
{
public:A(int a = 0):_a(a){cout << "A():" << this << endl;}~A(){cout << "~A()" << this << endl;}
private:int _a;
};//定位new/replacement new
int main()
{//p1現在指向的只不過是與A對象相同大小的空間,還不能算是一個對象,因為構造函數沒有執行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的區別

相同點: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在釋放空間前會調用析構函數完成空間中資源的清理

什么是內存泄露,內存泄露的危害

什么是內存泄露:內存泄露指因為疏忽或走錯屋造成程序未能釋放已經不再使用內存的情況。內存泄露并不是指內存在物理上的消失,而是應用程序分配某段內存后,因為設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費

內存泄露的危害:長期運行的程序出現內存泄露,影響很大,如操作系統、后臺服務,出現內存泄露會導致相應越來越慢,最終卡死

內存泄露的分類

堆內存泄露:

堆內存泄露是指程序執行中依據需要分配通過malloc/calloc/realloc/new等從堆中分配的一塊內存,用完后必須通過調用相應的free或者delete刪掉。假設程序的設計錯誤導致這部分內存沒有釋放,那么以后這部分空間將無法再被使用,就會產生Heap Leak

系統資源泄露:

指程序使用系統分配的資源,比如套接字、文件描述符、管道等沒有使用對應的函數釋放掉,導致系統資源的浪費,嚴重可導致系統效能的減少,系統執行不穩定

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716318.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716318.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716318.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024.03.01作業

1. 基于UDP的TFTP文件傳輸 #include "test.h"#define SER_IP "192.168.1.104" #define SER_PORT 69 #define IP "192.168.191.128" #define PORT 9999enum mode {TFTP_READ 1,TFTP_WRITE 2,TFTP_DATA 3,TFTP_ACK 4,TFTP_ERR 5 };void get_…

高維中介數據:基于交替方向乘子法(ADMM)的高維度單模態中介模型的參數估計(入門+實操)

全文摘要 用于高維度單模態中介模型的參數估計&#xff0c;采用交替方向乘子法&#xff08;ADMM&#xff09;進行計算。該包提供了確切獨立篩選&#xff08;SIS&#xff09;功能來提高中介效應的敏感性和特異性&#xff0c;并支持Lasso、彈性網絡、路徑Lasso和網絡約束懲罰等不…

npm 鏡像源切換與設置

項目背景 依賴安裝中斷或響應特別慢。 可以看到當前所用的鏡像是 https://registry.npmjs.org 。 切換淘寶鏡像之后總算能夠安裝下來 命令行模式 查看當前鏡像源 # 查看當前鏡像源 npm config get registry 可以看到默認情況下是官方默認全局鏡像 https://registry.npmjs.o…

競爭加劇下,登頂后的瑞幸該做什么?

瑞幸咖啡僅用短短18個月時間從品牌創立到納斯達克上市&#xff0c;刷新全球最快上市記錄。2020年因交易造假事件被勒令退市股價暴跌80%&#xff0c;有人說這個創造了赴美IPO奇跡的“巨嬰”將是下一個倒下的ofo。2023年瑞幸咖啡以逆勢超速增長領跑咖啡賽道有力回應了市場的質疑&…

Vector中的begin和end函數是左閉右開的區間

vector::end() 函數的語法 vector::end(); 參數&#xff1a; none——它什么都不接受。 返回值&#xff1a; iterator– 它返回一個指向向量的 past-the-end 元素的迭代器。 實際上Vector中的begin和end函數是左閉右開的區間。 例&#xff1a; Input: vector<int>…

Java多線程實現發布和訂閱

目錄 簡介 步驟 1: 定義消息類 步驟 2: 創建發布者 步驟 3: 創建訂閱者 步驟 4: 實現發布-訂閱模型 前言-與正文無關 生活遠不止眼前的苦勞與奔波&#xff0c;它還充滿了無數值得我們去體驗和珍惜的美好事物。在這個快節奏的世界中&#xff0c;我們往往容易陷入工作的漩渦…

棋牌室計時計費管理系統的燈控器連接教程

棋牌室計時計費管理系統的燈控器連接教程 一、前言 以下教程以 佳易王棋牌室計時計費管理系統軟件V18.0為例說明 軟件文件下載可以點擊最下方官網卡片——軟件下載——試用版軟件下載 如上圖&#xff0c;計時計費軟件在開始計時的時候&#xff0c;點擊 開始計時 如果連接了…

YOLOv9獨家改進|動態蛇形卷積Dynamic Snake Convolution與空間和通道重建卷積SCConv與RepNCSPELAN4融合

專欄介紹&#xff1a;YOLOv9改進系列 | 包含深度學習最新創新&#xff0c;主力高效漲點&#xff01;&#xff01;&#xff01; 一、改進點介紹 Dynamic Snake Convolution是一種針對細長微弱的局部結構特征與復雜多變的全局形態特征設計的卷積模塊。 SCConv是一種即插即用的空間…

華為OD機試真題C卷-篇6

100分值題 寬度最小的子矩陣部門人力分配電腦病毒感染會議室占用時間段 寬度最小的子矩陣 給定一個n行 * m列的矩陣&#xff1b;給定一個k個整數的數組k_list&#xff1b;在n*m的矩陣中找一個寬度最小的子矩陣&#xff0c;該子矩陣包含k_list中所有的整數&#xff1b; 輸入描述…

【大數據】Flink SQL 語法篇(九):Window TopN、Deduplication

《Flink SQL 語法篇》系列&#xff0c;共包含以下 10 篇文章&#xff1a; Flink SQL 語法篇&#xff08;一&#xff09;&#xff1a;CREATEFlink SQL 語法篇&#xff08;二&#xff09;&#xff1a;WITH、SELECT & WHERE、SELECT DISTINCTFlink SQL 語法篇&#xff08;三&…

COM - get VARIANT value - .vt = (VT_BSTR | VT_ARRAY)

文章目錄 COM - get VARIANT value - .vt (VT_BSTR | VT_ARRAY)概述筆記END COM - get VARIANT value - .vt (VT_BSTR | VT_ARRAY) 概述 取到一個VARIANT值, .vt 0x2008, 查了一下, 0x2008 (VT_BSTR | VT_ARRAY) 查了資料, 這個vt 0x2008是BSTR的數組. 看看咋取值? 網上…

3.2 log |416. 分割等和子集,1049.最后一塊石頭的重量II,494.目標和

416. 分割等和子集 class Solution { public:bool canPartition(vector<int>& nums) {vector<int> dp(10001,0);int sumaccumulate(nums.begin(),nums.end(),0);if(sum%2) return false;int targetsum/2;for(int i0;i<nums.size();i){for(int jtarget;j>…

項目管理:高效推動項目成功的關鍵

項目管理&#xff1a;高效推動項目成功的關鍵 在當今競爭激烈的商業環境中&#xff0c;項目管理已成為企業實現目標和取得成功的關鍵因素。有效的項目管理不僅能夠確保項目按時完成&#xff0c;還能在預算范圍內達到預期的質量標準。本文將探討項目管理的重要性、關鍵環節以及…

Maven安裝并配置本地倉庫

一、安裝Maven 1.下載鏈接 Maven官網下載鏈接 Binary是可執行版本&#xff0c;已經編譯好可以直接使用。 Source是源代碼版本&#xff0c;需要自己編譯成可執行軟件才可使用。 tar.gz和zip兩種壓縮格式,其實這兩個壓縮文件里面包含的內容是同樣的,只是壓縮格式不同 tar.gz格…

Stable Video文本生成視頻公測地址——Scaling Latent Video Diffusion Models to Large Datasets

近期&#xff0c;Stability AI發布了首個開放視頻模型——"Stable Video"&#xff0c;該創新工具能夠將文本和圖像輸入轉化為生動的場景&#xff0c;將概念轉換成動態影像&#xff0c;生成出電影級別的作品&#xff0c;旨在滿足廣泛的視頻應用需求&#xff0c;包括媒…

STM32 DMA入門指導

什么是DMA DMA&#xff0c;全稱直接存儲器訪問&#xff08;Direct Memory Access&#xff09;&#xff0c;是一種允許硬件子系統直接讀寫系統內存的技術&#xff0c;無需中央處理單元&#xff08;CPU&#xff09;的介入。下面是DMA的工作原理概述&#xff1a; 數據傳輸觸發&am…

解決Java并發問題的常見思路

寫在文章開頭 近期對一些比較老的項目進行代碼走查&#xff0c;碰到一些極端的并發編程惡習&#xff0c;所以筆者就基于此文演示這類問題以及面對并發編程時我們應該需要了解一些常見套路。 Hi&#xff0c;我是sharkChili&#xff0c;是個不斷在硬核技術上作死的java coder&am…

基于 Amazon EKS 的 Stable Diffusion ComfyUI 部署方案

01 背景介紹 Stable Diffusion 作為當下最流行的開源 AI 圖像生成模型在游戲行業有著廣泛的應用實踐&#xff0c;無論是 ToC 面向玩家的游戲社區場景&#xff0c;還是 ToB 面向游戲工作室的美術制作場景&#xff0c;都可以發揮很大的價值&#xff0c;如何更好地使用 Stable Dif…

scanf和cin的利弊

scanf和cin的利弊&#xff1a; scanf: 利&#xff1a;耗時短&#xff0c;寫法方便輸入固定格式&#xff0c;比如scanf(“%*d%d”,&a)&#xff0c;可以直接忽略第一個輸入&#xff0c;不用創建新對象&#xff0c;再比如scanf(“%1d”,&x[i])&#xff0c;輸入3214&#x…

卡牌——二分

卡牌 題目分析 想一下前面題的特點&#xff0c;是不是都出現了“最大邊長”&#xff0c;“最小的數”這種字眼&#xff0c;那么這里出現了“最多能湊出多少套牌”&#xff0c;我們可以考慮用二分。接下來我們要看一下他是否符合二段性&#xff0c;二分的關鍵在于二段性。 第…