最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++表達式new與delete知識詳解

 更新時間:2016年05月14日 16:20:13   作者:wqli  
這篇文章主要為大家詳細介紹了C++表達式new與delete知識點,學習如何動態(tài)創(chuàng)建對象,動態(tài)創(chuàng)建的對象與一般對象的區(qū)別,動態(tài)創(chuàng)建的對象的初始化以及釋放動態(tài)分配的內(nèi)存等知識點,感興趣的朋友可以參考一下

在C++中,new表達式用于動態(tài)創(chuàng)建對象,即在堆(自由存儲區(qū))空間上為對象分配內(nèi)存,而程序員也要小心的使用這些申請來的內(nèi)存空間,當不再使用時應(yīng)該調(diào)用delete表達式來釋放該存儲空間并且將指針置零。 本文學習了如何動態(tài)創(chuàng)建對象,動態(tài)創(chuàng)建的對象與一般對象的區(qū)別,動態(tài)創(chuàng)建的對象的初始化以及釋放動態(tài)分配的內(nèi)存等知識點。

C++中分配的內(nèi)存大致有三類:靜態(tài)存儲區(qū),棧內(nèi)存和堆內(nèi)存

其中,靜態(tài)存儲區(qū)是在程序編譯階段就已經(jīng)分配好的,用于全局變量,static變量等;堆棧是比較常用的對象存儲方式。

new和delete是C++中程序員申請和撤銷堆內(nèi)存的唯一方式(據(jù)我所知)。

1. 創(chuàng)建對象

無論是定義內(nèi)置類型變量還是類類型變量,都必須指定其對應(yīng)的數(shù)據(jù)類型和名字。

動態(tài)創(chuàng)建對象只需指定其數(shù)據(jù)類型,而不必為該對象命名。

也就是說,變量定義得到的對象可以通過額外定義的指針或其對象名本身來訪問,而動態(tài)創(chuàng)建方式得到的對象只能通過返回的指針來訪問,因為該對象并沒有名字。

2. 初始化

a. 可以在變量定義或是動態(tài)創(chuàng)建的階段初始化對象,例如:

int i(222); // definition, initialized
int *pi = new int(222) // dynamically, initialized

b. 在這還要說一說變量定義時的默認初始化問題:

內(nèi)置類型的變量初始化與其定義位置有關(guān):函數(shù)外的自動初始化為零,而函數(shù)內(nèi)的沒有初始化。對于類類型的變量,程序總是會調(diào)用默認構(gòu)造函數(shù)來初始化,這個默認構(gòu)造函數(shù)可以是系統(tǒng)自動生成的,也可以是程序員定義的。如果沒有默認構(gòu)造函數(shù),那么該類型變量的定義也就不能采用默認初始化方式,必須提供顯式的初始化式。

動態(tài)創(chuàng)建的對象默認初始化與函數(shù)內(nèi)變量定義的初始化方式相同,例如:

string *ps = new string; // initialized to empty string
int *pi = new int; // pi points to an uninitialized int

c. 動態(tài)創(chuàng)建對象的值初始化(value-initialize)

這種值初始化不能用于變量定義,而只能用于動態(tài)創(chuàng)建方式。

string *ps2 = new string(); // initialized to empty string
int *pi = new int(); // pi points to an int value-initialized to 0

值初始化表明程序員想要做初始化,但并未提供特定的初值。實際上,對于提供了默認構(gòu)造函數(shù)的類類型(如string),沒有必要對其對象進行值初始化:無論程序是明確地不初始化還是要求進行值初始化,都會自動調(diào)用其默認構(gòu)造函數(shù)初始化該對象。值初始化真正有用的是對于內(nèi)置類型。另外需要注意的一點是,值初始化的 () 語法必須置于類型名后面,而不是變量名后面,否則得到的是一個函數(shù)聲明,如下:

int myValue(); // not value-initialized int variable, but a function named myValue
int *myPtr = new int(); // correct! a value-initialized int object

對于沒有默認構(gòu)造函數(shù)的類類型,無論是變量定義還是動態(tài)創(chuàng)建對象都必須采用顯式初始化。

3. 撤銷對象

動態(tài)創(chuàng)建的對象用完后,程序員必須顯式地將該對象占用的內(nèi)存返還給自由存儲區(qū)。C++提供了delete表達式釋放指針所指向的地址空間。

delete myPtr;
上述語句釋放 myPtr 指向的 int 型對象所占用的內(nèi)存。

C++沒有明確定義如何釋放指向不是用 new 分配的內(nèi)存地址的指針。此外,編譯器通常不能斷定一個指針究竟指向什么類型的對象,因此如果調(diào)用delete 企圖釋放指向棧內(nèi)存地址的指針時,編譯器并不會報錯,但請盡量不要依賴于該未定義的行為。

在C++中 delete 一個零值指針是合法且安全的,但實際上毫無意義。

懸垂指針(dangling pointer)

刪除了指針所指向的對象后,該指針變成懸垂指針。懸垂指針指向曾經(jīng)存放對象的內(nèi)存,但該對象實際已經(jīng)不存在了。懸垂指針往往導(dǎo)致程序錯誤,并且很難檢測。因此,在調(diào)用delete 釋放指針所指對象內(nèi)存后應(yīng)該立刻將指針置零。

4. Const 對象的動態(tài)分配和回收

const 對象,必須在定義階段或動態(tài)創(chuàng)建階段進行初始化,并且初始化之后其值不能再修改。

與其他 const 對象的地址一樣,由于 new 返回的地址上存放的是 const 對象,因此該地址只能賦給指向 const 的指針。

// allocate and initialize a const object
const int *pci = new const int(222); // initialize to 222
const int *pci2 = new const int();  // initialize to 0

盡管程序員不能改變 const 對象的值,但可撤銷對象本身。

delete pci; // ok: delete a const object
三種常見的程序錯誤都與動態(tài)內(nèi)存分配相關(guān):

1、刪除動態(tài)分配內(nèi)存失敗,稱為內(nèi)存泄漏(memory leak)
2、讀寫已刪除的對象
3、對同一個內(nèi)存空間使用兩次 delete 表達式。當兩個指針指向同一個動態(tài)創(chuàng)建的對象,刪除時就會發(fā)生錯誤。第二個指針的 delete 操作往往會破壞自由存儲區(qū)。
個人實踐部分:

#include <iostream>
#include <cstring>
using namespace std;

int main(void)
{
  string str = "hello str";
  // strNew points to dynamically allocated,
  // initialized to empty string
  string *strNew = new string;
  
  cout<<"str object address: "<<&str<<endl;
  cout<<"strNew pointer itself address: "<<&strNew<<endl;
  cout<<"strNew pointer to address: "<<strNew<<endl;
  
  // assignment
  *strNew = "hello strNew";
  cout<<"strNew pointer to address: "<<strNew<<endl;
  
  // free memory
  delete strNew;
  cout<<"strNew pointer to address: "<<strNew<<endl;
  strNew = NULL;
  
  // point to other object
  strNew = &str;
  cout<<"strNew pointer to address: "<<strNew<<endl;
  
  
  const int cvalue(10);
  // iptr points to a const int object
  const int *iptr = new const int(222);
  cout<<"iptr value: "<<*iptr<<endl;
  delete iptr;
  iptr = NULL;
  
  iptr = &cvalue;
  cout<<"iptr value: "<<*iptr<<endl;
  
  return 0;
}


一次運行的結(jié)果如下:

str object address: 0x28ff24
strNew pointer itself address: 0x28ff20
strNew pointer to address: 0x602f70
strNew pointer to address: 0x602f70
strNew pointer to address: 0x602f70
strNew pointer to address: 0x28ff24
iptr value: 222
iptr value: 10

程序中間將原來指向 new 創(chuàng)建的對象的指針重定向到一般的變量,可以看到指針存放地址的改變。另外需要注意,在釋放 new 對象之前不要將指針重新指向某個其他對象,這樣會導(dǎo)致原來動態(tài)創(chuàng)建的對象沒有指針指向它,無法釋放內(nèi)存空間。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助。

相關(guān)文章

  • C++實現(xiàn)Matlab的zp2tf函數(shù)的示例代碼

    C++實現(xiàn)Matlab的zp2tf函數(shù)的示例代碼

    matlab?的?zp2tf?函數(shù)的作用是將極點形式的?H(s)?函數(shù)的分母展開,本文主要為大家介紹了C++實現(xiàn)Matlab的zp2tf函數(shù)示例代碼,需要的可以參考一下
    2023-04-04
  • C語言小程序 如何判斷兩個日期之差

    C語言小程序 如何判斷兩個日期之差

    輸入兩個日期,計算之間相差多少天。 用了兩種方法實現(xiàn),第二種利用結(jié)構(gòu)體,代碼比較清晰,其余的都一樣
    2013-07-07
  • C語言中sizeof 和 strlen的區(qū)別

    C語言中sizeof 和 strlen的區(qū)別

    sizeof?和?strlen?是兩個常用于 C/C++ 語言中的函數(shù)或操作符,本文主要介紹了C語言中sizeof 和 strlen的區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • C++去除輸入行中空白的方法

    C++去除輸入行中空白的方法

    這篇文章主要介紹了C++去除輸入行中空白的方法,涉及C++針對數(shù)組的遍歷與替換的相關(guān)使用技巧,需要的朋友可以參考下
    2015-07-07
  • C++預(yù)處理連接的示例詳解

    C++預(yù)處理連接的示例詳解

    C++預(yù)處理連接(Preprocessor?Concatenation)是一種宏定義技巧,用于將兩個或多個符號(如變量、字符串等)連接成一個符號。這篇文章主要通過一些示例為大家講解一下預(yù)處理連接,需要的可以參考一下
    2023-03-03
  • C++直接初始化與復(fù)制初始化的區(qū)別深入解析

    C++直接初始化與復(fù)制初始化的區(qū)別深入解析

    這篇文章主要介紹了C++直接初始化與復(fù)制初始化的區(qū)別深入解析,是很多C++初學者需要深入了解的重要概念,需要的朋友可以參考下
    2014-09-09
  • C++分析構(gòu)造函數(shù)與析造函數(shù)的特點梳理

    C++分析構(gòu)造函數(shù)與析造函數(shù)的特點梳理

    本文對類的構(gòu)造函數(shù)和析構(gòu)函數(shù)進行總結(jié),主要包括了構(gòu)造函數(shù)的初始化、重載、使用參數(shù)和默認參數(shù),拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù),希望能幫助讀者在程序開發(fā)中更好的理解類,屬于C/C++基礎(chǔ)
    2022-05-05
  • 深入單鏈表的快速排序詳解

    深入單鏈表的快速排序詳解

    本篇文章是對單鏈表的快速排序進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++繼承類成員訪問權(quán)限修飾符詳解

    C++繼承類成員訪問權(quán)限修飾符詳解

    這篇文章主要為大家介紹了C++繼承類成員訪問權(quán)限修飾符,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • C++踩坑實戰(zhàn)之構(gòu)造和析構(gòu)函數(shù)

    C++踩坑實戰(zhàn)之構(gòu)造和析構(gòu)函數(shù)

    不論是構(gòu)造函數(shù),還是析構(gòu)函數(shù),都是C++、C#語言相對于其他語言而言特殊的地方,它是為了方便類中對象的初始化,這篇文章主要給大家介紹了關(guān)于C++踩坑實戰(zhàn)之構(gòu)造和析構(gòu)函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07

最新評論

修水县| 商河县| 武乡县| 中超| 印江| 隆德县| 勐海县| 丽水市| 莫力| 措美县| 云梦县| 南宫市| 乐昌市| 黄骅市| 汨罗市| 共和县| 上栗县| 陇南市| 平和县| 台中市| 闽清县| 高台县| 绥滨县| 卢氏县| 楚雄市| 安西县| 科尔| 广平县| 靖宇县| 铅山县| 盐津县| 兰州市| 灵丘县| 吴桥县| 民和| 洮南市| 多伦县| 南皮县| 体育| 拉萨市| 沁阳市|