網站首頁 編程語言 正文
下面是《C++ Primer 5th》中P726 對 new 和 delete 過程的解釋:
當我們使用一條new表達式時,實際上執行了三步操作:
- new表達式調用一個名為 operator new (或者 operator new[] )的標準庫函數。該函數分配一塊足夠大的、原始的、未命名的內存空間以便存儲特定類型的對象(或者對象數組)。
- 編譯器運行相應的構造函數以構造這些對象,并為其傳入初始值。
- 對象被分配了空間并構造完成,返回一個指向該對象的指針。
當我們使用一條delete表達式時,實際上執行了兩步操作:
- 對sp所指的對象或者arr所指的數組中的元素執行相應的析構函數。
- 編譯器調用名為 operator delete (或者 **operator delete[] **)的標準庫函數釋放內存空間。
由于不同編譯器對new的實現過程不同,所以我們下面以侯捷老師課件來進行詳解。
new
假設我們現在有一個類: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為類名(復數)
編譯器處理new這一語句的時候,先分配復數的內存,然后進行轉型,最后調用構造函數,進行了下面三個過程
void* men= operator new( sizeof(Complex));//第一步,分配內存
pc = static_cast<Complex*>(men);//第二步,轉型
pc->Complex :: Complex(1,2);//第三步,調用構造函數
下面是在VS2019上反匯編得到:
整體示意圖如下:
delete
當我們進行 delete 操作時:
delete pc;
在編譯器的處理過程中,這一語句轉化兩個步驟:先析構再free
Complex::~Complex(pc);//析構函數
operator delete(pc);//釋放內存
下面是在VS2019上反匯編得到:
示意圖如下:
整體代碼如下:
int main() {
Complex* pc = new Complex(1, 2);
cout << pc->imag() << ":" << pc->real() << endl;
delete pc;
system("pause");
return 0;
}
整體程序運行結果如下:
new[]
假設我們有一個類 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));//第一步,分配內存
ps = static_cast<MyString*>(men);//第二步,轉型
ps->MyString:: MyString("Hello");//第三步,調用構造函數
下面是在VS2019上反匯編得到:
示意圖如下:
delete[]
當我們進行 delete 操作時:
delete ps;
在編譯器的處理過程中,這一語句轉化兩個步驟:先析構再free
MyString::~MyString(ps);//析構函數
operator delete(ps);//釋放內存
下面是在VS2019上反匯編得到:
示意圖如下:
整體代碼如下:
int main() {
MyString* ps = new MyString("Hello");
cout << ps->get_c_str() << endl;
delete ps;
system("pause");
return 0;
}
整體程序運行結果如下:
原文鏈接:https://blog.csdn.net/qq_43142509/article/details/125446938
相關推薦
- 2023-02-12 Golang中反射的常見用法分享_Golang
- 2022-07-29 Docker容器的加載分層原理及commit鏡像_docker
- 2023-01-27 goroutine?泄漏和避免泄漏實戰示例_Golang
- 2023-05-19 python?txt中的文件,逐行讀取并且每行賦值給變量問題_python
- 2022-07-08 PyHacker編寫指南引用Nmap模塊實現端口掃描器_python
- 2022-03-15 Docker Run Cadvisor failed: inotify_add_watch /sy
- 2022-06-28 詳解Python中遞歸函數的原理與使用_python
- 2023-03-18 pandas預處理部分地區數據案例_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支