C++類和new、delete操作符和堆和棧記憶體的分配
如果你是Java、C#、PHP程式設計師,那麼會對 new 非常熟悉,在這些程式語言中,只能通過 new 來建立物件。在C++中,你可以像定義變數一樣來建立物件,如:
- Studentstu; //物件已被例項化,已分配記憶體空間,可以使用了
- stu.say(); //呼叫成員函式
當發生函式呼叫時,系統將函式引數、區域性變數、區域性物件依次壓入棧區;函式執行結束,再按照先進後出的原則將它們彈出(銷燬)。
對於大部分程式,這不會有什麼問題。但當你希望在函式呼叫結束前銷燬物件時,你是無能為力的。或者你希望通過 for 迴圈來建立多個物件,這種方法同樣也做不到。
這個時候 new 和 delete 就派上了用場:使用 new 建立的物件,可以在任意時刻通過 delete 銷燬,而且只需要一個指標指向它。
以前面的 Student 類為例,可以這樣來動態建立物件:
new Student;也可以使用建構函式:
new Student("小明", 15, 90.5f);這樣,就在堆區為物件分配了記憶體,並呼叫了建構函式。
但是此時程式設計師還無法訪問這個物件,因為這個物件既沒有名字,也沒有指標指向它。這種物件稱為匿名物件,它確實存在,但無法訪問。
用一個指標來指向Student類的物件:
Student *pStu; pStu = new Student("小明", 15, 90.5f);
Student *pStu = new Student("小明", 15, 90.5f);
當不再需要物件時,可以通過 delete 銷燬:
delete pStu;這樣,就釋放掉了物件佔用的記憶體,並呼叫了解構函式。
需要說明的是:new 在堆區為物件分配記憶體。與棧區不同的是,堆區記憶體由程式設計師分配和釋放,系統不會自動銷燬,即使函式呼叫結束了,仍然會保留堆區記憶體。如果程式設計師不主動回收堆區記憶體,那麼只能在程式執行結束後由作業系統回收。
為了避免記憶體洩露,強烈建議 new 和 delete 成對出現,及時銷燬不再需要的物件。
例如,下面的程式碼會造成嚴重的記憶體洩露:
- #include
- #include <cstdlib>
- using namespace std;
- classDemo{
- private:
- double n;
- double m;
- int i;
- };
- void func(){
- Demo*p = new Demo;
- }
- int main(){
- int i;
- for(i=1; i<=1000000; i++){
- func();
- }
- system("pause");
- return 0;
- }
這是因為每次呼叫 func 函式,都會建立一個物件,並用 p 指向它。函式執行結束,僅僅釋放了指標變數 p 佔用的記憶體,而沒有釋放 p 所指向的物件佔用的記憶體。
如果在 func 函式中不回收物件記憶體,那麼你將永遠無法回收,只能等到程式執行結束由作業系統回收,這就是典型的記憶體洩露。
另外注意,C語言中的 malloc、free 函式不能用來為物件分配和釋放記憶體。請看下面的例子:
- #include <iostream>
- using namespace std;
- classDemo{
- public:
- Demo();
- ~Demo();
- };
- Demo::Demo(){
- cout<<"Constructor"<<endl;
- }
- Demo::~Demo(){
- cout<<"Destructor"<<endl;
- }
- int main(){
- cout<<"------new------"<<endl;
- Demo*p1 = new Demo; //建立一個物件
- Demo*p2 = new Demo[5]; //建立一組物件
- cout<<"------malloc------"<<endl<<endl;
- Demo*p3 = (Demo*)malloc(sizeof(Demo));
- cout<<"------delete------"<<endl;
- delete p1; //銷燬一個物件
- delete[] p2; //銷燬一組物件
- cout<<"------free------"<<endl;
- free(p3);
- return 0;
- }
------new------
Constructor
Constructor
Constructor
Constructor
Constructor
Constructor
------malloc------
------delete------
Destructor
Destructor
Destructor
Destructor
Destructor
Destructor
------free------
從程式執行結果可以看出:malloc 雖然分配了記憶體,但沒有呼叫建構函式;free 雖然釋放了記憶體,但也沒有呼叫解構函式。
相關推薦
C++類和new、delete操作符和堆和棧記憶體的分配
如果你是Java、C#、PHP程式設計師,那麼會對 new 非常熟悉,在這些程式語言中,只能通過 new 來建立物件。 在C++中,你可以像定義變數一樣來建立物件,如: Studentstu; //物件已被例項化,已分配記憶體空間,可以使用了stu.say();
C++運算符new、delete
C++在軟件開發中過程中,常常需要動態地分配和撤銷內存空間,例如對動態鏈表中結點的插入與刪除。 new int; //開辟一個存放整數的存儲空間,返回一個指向該存儲空間的地址(即指針)。 new int(100); //指定該整數的初值為100 new char[10]; //包含10個字符的空間 new
2.16 C++類與new和delete操作符
運行 out 可能 clas cout std 存儲 分配 程序 參考: http://www.weixueyuan.net/view/6347.html 總結: 當我們需要為類對象動態分配存儲空間時,我們應該使用C++語言提供的new與new[]操作符,而不要使用C
C++——建立類的時候用new與不用new 的區別(從堆和棧的解讀)
轉自:https://www.cnblogs.com/tony-li/p/4111588.html C++在建立物件的時候可以採用兩種方式:(例如類名為Test) Test test 或者 Test* pTest = new Test()。 這兩
C++中重載、重寫(覆蓋)和隱藏的區別
post space csdn depend amp 不同類 sin ase 返回 轉載自:https://blog.csdn.net/zx3517288/article/details/48976097 基本概念: 重載:是指同一可訪問區內被聲明的幾個具有不同參數列(參數
Linux後臺進程管理以及ctrl+z(掛起)、ctrl+c(中斷)、ctrl+(退出)和ctrl+d(EOF)的區別(轉)
列表 art 信息 csdn 而是 png detail tps 後臺 一、後臺進程管理命令 fg、bg、jobs、&、ctrl + z、ctrl + c、ctrl + \、ctrl + d1、 &加在一個命令的最後,可以把這個命令放到後臺執行 ,如fire
PHP設計模式:類自動載入、PSR-0規範、鏈式操作、11種面向物件設計模式實現和使用、OOP的基本原則和自動載入配置
一、類自動載入 SPL函式 (standard php librarys) 類自動載入,儘管 __autoload() 函式也能自動載入類和介面,但更建議使用&nbs
C++之new、delete 與malloc、free
在C/C++程式設計中經常會申請記憶體,而對記憶體的申請釋放操作有兩套方法: new、delete 與malloc、free。 1. 區別 (1). new、delete是c++中的操作符,malloc、free是C中的一個函式,它們都可用於申請動態記憶體和釋放記憶體。 (2)
C語言的指標、連結串列的原理和各類操作
一、指標 1、運用指標 什麼是指標?什麼是記憶體地址?什麼叫做指標的取值?指標是一個儲存計算機記憶體地址的變數。從指標指向的記憶體讀取資料稱作指標的取值。指標可以指向某些具體型別的變數地址,例如int、long和double。指標也可以
Java物件和例項的關係、Java資料封裝、Java繼承和多型、Java抽象類和介面、Java靜態欄位和方法、Java包和作用域、Java的classpath和jar、Java核心類
Java物件和例項的關係: 面向物件程式設計(Object-Oriented Programming),是對現實世界建立計算機模型的一種方法。 class是物件的模板,它定義瞭如何建立例項,class的名字就是資料型別。一個class裡可以有多個欄位(field),欄位用
ORACLE觸發器和new、old特殊變數
:new --為一個引用最新的列值; :old --為一個引用以前的列值; 這兩個變數只有在使用了關鍵字 "FOR EACH ROW"時才存在.且update語句兩個都有,而insert只有:new ,delect 只有:old; 系統中的觸發器例項: create or replace trigger J
c++のstatic靜態成員、物件的動態建立和釋放
1、靜態成員變數 (1)核心思想 靜態成員變數的初始化必須在類的外部,也可以通過物件直接進行賦值; 靜態函式的只能使用靜態成員變數,不能使用其他普通的成員變數; (2)程式碼例子邊看邊講解 #include <stdio.h> cla
C++ 用new 、delete 動態建立、刪除陣列
指標名直接作為引數傳遞給函式時{ int *p; fun(p) },傳遞的是指標的值,不是指標的地址,所以被調函式無法修改傳入指標的值。如果要對實參p做賦值操作,有兩種方法,1,傳遞實參的地址 &pvoid fun(int **pp);int *p;fun(&
面試題:C++有了malloc/free,為什麼還需要new、delete?
1、面試寶典面試題(P81):C++有了malloc/free,為什麼還需要new、delete? malloc與free是C、C++語言的標準庫函式,new/delete是C++的運算子。他們都用於申請動態記憶體和釋放記憶體。 對於非內部資料型別的物件而言,只用mall
Linux後臺程序管理以及ctrl+z(掛起)、ctrl+c(中斷)、ctrl+\(退出)和ctrl+d(EOF)的區別
轉自:http://blog.csdn.net/fengyifei11228/article/details/5737371 http://idas643.blog.163.com/blog/static/1671048382013414938465
C ++的new、delete
當寫出p = new P();這樣的程式碼的時候, 實際上有兩步操作, 首先分配記憶體,然後在分配好的記憶體之上初始化類成員.第二步是有建構函式完成的, 第一步就是new函式的工作.全域性的new有六種過載形式,void *operator new(std::size_t
用C++模板來展示new與delete操作符原理
C++中的new與delete可以認為是C中的malloc與free的升級版本。 new包含兩部分,一部分是與malloc功能相同,是從堆上面申請記憶體塊,第二部是呼叫類的構造方法來初始化剛申請的記憶體。 delete是new的逆過程,先呼叫類的析構方法來反初始化,再
C++的new、delete及其記憶體管理
程式碼寫多了,就麻木了。new和delete很好用,平時用的時候沒想太多。但如果“想太多”就會引發出很多東西。 new和delete跟sizeof一樣,是操作符,關鍵字,而不是函式。new和delete比malloc和free具有更強的功能。 new和delete用於動態
c++類的拷貝、賦值與銷毀(拷貝構造函數、拷貝賦值運算符析構函數)
錯誤 保存 編譯 oid 生成 標準庫 int 為什麽 explicit 拷貝構造函數 如果一個構造函數的第一個參數是自身類類型的引用,且任何額外參數都有默認值,則此構造函數是拷貝構造函數。 拷貝構造函數第一個參數必須是一個引用類型。此參數幾乎總是一個con
Java的知識點6—— 強制型別轉換、基本型別轉化時常見錯誤和問題、 簡單的鍵盤輸入和輸出
強制型別轉換 強制型別轉換,又被稱為造型,用於顯式的轉換一個數值的型別。在有可能丟失資訊的情況下進行的轉換是通過造型來完成的,但可能造成精度降低或溢位。 public class Test2 { public static void main(String [] ar