最新C/C++中的new和delete的實(shí)現(xiàn)過程小結(jié)
下面是《C++ Primer 5th》中P726 對 new 和 delete 過程的解釋:
當(dāng)我們使用一條new表達(dá)式時,實(shí)際上執(zhí)行了三步操作:
- new表達(dá)式調(diào)用一個名為 operator new (或者 operator new[] )的標(biāo)準(zhǔn)庫函數(shù)。該函數(shù)分配一塊足夠大的、原始的、未命名的內(nèi)存空間以便存儲特定類型的對象(或者對象數(shù)組)。
- 編譯器運(yùn)行相應(yīng)的構(gòu)造函數(shù)以構(gòu)造這些對象,并為其傳入初始值。
- 對象被分配了空間并構(gòu)造完成,返回一個指向該對象的指針。
當(dāng)我們使用一條delete表達(dá)式時,實(shí)際上執(zhí)行了兩步操作:
- 對sp所指的對象或者arr所指的數(shù)組中的元素執(zhí)行相應(yīng)的析構(gòu)函數(shù)。
- 編譯器調(diào)用名為 operator delete (或者 **operator delete[] **)的標(biāo)準(zhǔn)庫函數(shù)釋放內(nèi)存空間。
由于不同編譯器對new的實(shí)現(xiàn)過程不同,所以我們下面以侯捷老師課件來進(jìn)行詳解。
new
假設(shè)我們現(xiàn)在有一個類:complex.h
#ifndef __MYCOMPLEX__ #define __MYCOMPLEX__ class Complex { public: Complex(double r = 0, double i = 0) :m_real(r), m_imag(i) {} double real() const { return m_real; } double imag() const { return m_real; } private: double m_real; double m_imag; }; #endif
我們new一個對象
Complex* pc = new Complex(1,2);//Complex為類名(復(fù)數(shù))
編譯器處理new這一語句的時候,先分配復(fù)數(shù)的內(nèi)存,然后進(jìn)行轉(zhuǎn)型,最后調(diào)用構(gòu)造函數(shù),進(jìn)行了下面三個過程
void* men= operator new( sizeof(Complex));//第一步,分配內(nèi)存 pc = static_cast<Complex*>(men);//第二步,轉(zhuǎn)型 pc->Complex :: Complex(1,2);//第三步,調(diào)用構(gòu)造函數(shù)
下面是在VS2019上反匯編得到:
整體示意圖如下:
delete
當(dāng)我們進(jìn)行 delete 操作時:
delete pc;
在編譯器的處理過程中,這一語句轉(zhuǎn)化兩個步驟:先析構(gòu)再free
Complex::~Complex(pc);//析構(gòu)函數(shù) operator delete(pc);//釋放內(nèi)存
下面是在VS2019上反匯編得到:
示意圖如下:
整體代碼如下:
int main() { Complex* pc = new Complex(1, 2); cout << pc->imag() << ":" << pc->real() << endl; delete pc; system("pause"); return 0; }
整體程序運(yùn)行結(jié)果如下:
new[]
假設(shè)我們有一個類 MyString.h
#ifndef __MYSTRING__ #define __MYSTRING__ #include <string> class MyString { public: MyString(const char* cstr = 0) { if (cstr) { m_data = new char[strlen(cstr) + 1]; strcpy(m_data, cstr); } else { m_data = new char[1]; *m_data = '\0'; } } ~MyString() { delete[] m_data; } char* get_c_str() const { return m_data; } private: char* m_data; }; #endif
我們new一個對象
MyString* ps = new MyString("Hello");
編譯器處理new這一語句的時候,也是分為三個過程,與上相同
void* men= operator new( sizeof(MyString));//第一步,分配內(nèi)存 ps = static_cast<MyString*>(men);//第二步,轉(zhuǎn)型 ps->MyString:: MyString("Hello");//第三步,調(diào)用構(gòu)造函數(shù)
下面是在VS2019上反匯編得到:
示意圖如下:
delete[]
當(dāng)我們進(jìn)行 delete 操作時:
delete ps;
在編譯器的處理過程中,這一語句轉(zhuǎn)化兩個步驟:先析構(gòu)再free
MyString::~MyString(ps);//析構(gòu)函數(shù) operator delete(ps);//釋放內(nèi)存
下面是在VS2019上反匯編得到:
示意圖如下:
整體代碼如下:
int main() { MyString* ps = new MyString("Hello"); cout << ps->get_c_str() << endl; delete ps; system("pause"); return 0; }
整體程序運(yùn)行結(jié)果如下:
到此這篇關(guān)于C/C++中的new和delete的實(shí)現(xiàn)過程的文章就介紹到這了,更多相關(guān)C++ new和delete內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++函數(shù)三種傳參形式(指針傳遞、引用傳遞、值傳遞)
不論是哪種參數(shù)傳遞方式,都有形參和實(shí)參之分,本文主要介紹了C++函數(shù)三種傳參形式(指針傳遞、引用傳遞、值傳遞),具有一定的參考價值,感興趣的可以了解一下2024-03-03C語言開發(fā)實(shí)現(xiàn)井字棋及電腦落子優(yōu)化示例詳解
以前上課經(jīng)常和同桌玩起井字棋,那么我們就當(dāng)我們回憶童年,現(xiàn)在也用C語言來實(shí)現(xiàn)井字棋,本次代碼相對于初階的井字棋,在電腦下棋代碼部分做了優(yōu)化,使得電腦更加具有威脅2021-11-11VS2022永久配置OpenCV開發(fā)環(huán)境的實(shí)現(xiàn)
本文主要介紹了VS2022永久配置OpenCV開發(fā)環(huán)境的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無法使用萬能頭<bits/stdc++.h>的
如果大家也遇到下面這種問題,可能是沒有include文件夾中沒有bits/stdc++.h,這篇文章主要介紹了Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無法使用萬能頭<bits/stdc++.h>的解決方案,感興趣的朋友跟隨小編一起看看吧2024-02-02C語言putenv()函數(shù)和getenv()函數(shù)的使用詳解
這篇文章主要介紹了C語言putenv()函數(shù)和getenv()函數(shù)的使用詳解,用來進(jìn)行環(huán)境變量的相關(guān)操作,需要的朋友可以參考下2015-09-09