亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++淺拷貝與深拷貝及引用計數分析

2020-01-26 14:05:36
字體:
來源:轉載
供稿:網友

C++淺拷貝與深拷貝及引用計數分析

在C++開發中,經常遇到的一個問題就是與指針相關的內存管理問題,稍有不慎,就會造成內存泄露、內存破壞等嚴重的問題。不像Java一樣,沒有指針這個概念,所以也就不必擔心與指針相關的一系列問題,但C++不同,從C語言沿襲下來的指針是其一大特點,我們常常要使用new/delete來動態管理內存,那么問題來了,特別是伴隨著C++的繼承機制,如野指針、無效指針使用、內存泄露、double free、堆碎片等等,這些問題就像地雷一樣,一不小心就會踩那么幾顆。

先來談一下C++類中常見的淺拷貝問題,以及由此引發的double free。什么是淺拷貝?當類中的成員變量包括指針時,而又沒有定義自己的拷貝構造函數,那么在拷貝一個對象的情況下,就會調用其默認拷貝構造函數,其實這個函數沒做什么事,只是對其成員變量作了個簡單的拷貝,也就是所謂的位拷貝,它們指向的還是同一個存儲空間,當對象析構時,就會析構多次,也就是double free,下面舉例說明。

class Common{public:  Common()  {    std::cout << "Common::Common" << std::endl;  }  Common(const Common &r)  {    std::cout << "Common::Common copy-constructor" << std::endl;  }  ~Common()  {    std::cout << "Common::~Common" << std::endl;  }};

類Common是個一般的類,定義了構造、拷貝構造和析構函數,在函數里輸出一些log,用以跟蹤函數調用情況。

class BitCopy{public:  BitCopy()    : m_p(new Common)  {    std::cout << "BitCopy::BitCopy" << std::endl;  }  ~BitCopy()  {    std::cout << "BitCopy::~BitCopy" << std::endl;    if (m_p) {      delete m_p;      m_p = NULL;    }  }private:  Common *m_p;};

類BitCopy就是一個淺拷貝類,成員變量是我們剛定義的類指針,構造函數實例化成員變量,析構函數delete成員變量,沒有定義拷貝構造函數。

int main(){  BitCopy a;  BitCopy b(a);  return 0;}log如下:Common::CommonBitCopy::BitCopyBitCopy::~BitCopyCommon::~CommonBitCopy::~BitCopyCommon::~Common*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001f4e010 ***已放棄 (核心已轉儲)

從上面的log可以看出,對象a調用了構造函數,對象b調用的是默認拷貝構造函數,最后析構了兩次,從而造成double free,核心已轉儲即core dump。

針對以上問題,該怎么解決呢?有兩個辦法,一個是深拷貝,一個是引用計數。先來看一下深拷貝,深拷貝要定義自己的拷貝構造函數,在函數中給成員變量重新分配存儲空間,也就是所謂的值拷貝,這樣它們所指向的就是不同的存儲空間,析構時不會有問題,但這種方法只適用于較小的數據結構,如果數據結構過大,多次分配存儲空間之后,剩余的存儲空間將逐漸減小,

下面看個例子。

class ValueCopy{public:  ValueCopy()    : m_p(new Common)  {    std::cout << "ValueCopy::ValueCopy" << std::endl;  }  ValueCopy(const ValueCopy &r)    : m_p(new Common(*r.m_p))  {    std::cout << "ValueCopy::ValueCopy copy-constructor" << std::endl;  }  ~ValueCopy()  {    std::cout << "ValueCopy::~ValueCopy" << std::endl;    if (m_p) {      delete m_p;      m_p = NULL;    }  }private:  Common *m_p;};

類ValueCopy是個深拷貝類,與上面例子的淺拷貝類不同的是定義了拷貝構造函數,在函數中給成員變量重新分配存儲空間,下面是用法及log。

int main(){  ValueCopy c;  ValueCopy d(c);  return 0;}Common::CommonValueCopy::ValueCopyCommon::Common copy-constructorValueCopy::ValueCopy copy-constructorValueCopy::~ValueCopyCommon::~CommonValueCopy::~ValueCopyCommon::~Common

從上面的log可以看出,對象c調用了構造函數,對象d調用的是自定義拷貝構造函數,最后析構了兩次而沒有問題,可見深拷貝的用處所在。

引用計數與深拷貝不同,方法是共享同一塊存儲空間,這個對大的數據結構比較有利。使用引用計數,需要在類中定義一個成員變量專門用于計數,初始值為1,后面引用了這個對象就加1,對象銷毀時引用減1,但并不真正的delete這個對象,只有當這個成員變量的值為0時才進行delete,例子如下。

class A{public:  A()    : m_refCount(1)  {    std::cout << "A::A" << std::endl;  }  A(const A &r)    : m_refCount(1)  {    std::cout << "A::A copy-constructor" << std::endl;  }  ~A()  {    std::cout << "A::~A" << std::endl;  }  void attach()  {    std::cout << "A::attach" << std::endl;    ++m_refCount;  }  void detach()  {    if (m_refCount != 0) {      std::cout << "A::detach " << m_refCount << std::endl;      if (--m_refCount == 0) {        delete this;      }    }  }private:  int m_refCount;};class B{public:  B()    : m_pA(new A)  {    std::cout << "B::B" << std::endl;  }  B(const B &r)    : m_pA(r.m_pA)  {    std::cout << "B::B copy-constructor" << std::endl;    m_pA->attach();  }  ~B()  {    std::cout << "B::~B" << std::endl;    m_pA->detach();  }private:  A* m_pA;};

類A用到了引用計數,構造和拷貝構造函數都初始化為1,attach()函數為引用加1,detach()函數為引用減1,當引用計數值為0時delete對象。類B中的成員變量有個指針指向A,拷貝構造函數中調用了attach(),析構函數中調用了detach(),這樣也是一種保護,不會有內存泄露,也不會有double free,log如下。

int main(){  B e;  B f(e);  return 0;}A::AB::BB::B copy-constructorA::attachB::~BA::detach 2B::~BA::detach 1A::~A

從log中可以看出,指針成員變量的引用計數為2,這是正確的,最后正確delete,沒有問題。

在類中只要有指針成員變量,就要注意以上問題,另外,operator=這個賦值操作符也要在適當的時候進行重載。有時候,如果想規避以上問題,可以聲明拷貝構造函數和operator=操作符為private而不去實現它們。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美在线视频| 精品亚洲一区二区三区在线播放| 亚洲xxxx妇黄裸体| 成人黄色av免费在线观看| 精品福利在线观看| 精品久久久在线观看| 国产福利视频一区二区| 青青草精品毛片| 国产中文字幕日韩| 日本人成精品视频在线| 亚洲精品一区中文字幕乱码| 亚洲国产中文字幕在线观看| 日韩av免费在线看| 日韩电影在线观看永久视频免费网站| 亚洲欧美日韩精品| 亚洲韩国青草视频| 亚洲欧美在线看| 91精品国产成人www| 日韩中文字幕在线视频| 欧美另类第一页| 日韩欧美精品网站| 亚洲欧洲黄色网| 8x海外华人永久免费日韩内陆视频| 精品视频www| 日韩av在线免播放器| 九九九热精品免费视频观看网站| 久久91亚洲精品中文字幕奶水| 91av视频在线| 国产精品入口夜色视频大尺度| 国产精品三级久久久久久电影| 一本色道久久综合狠狠躁篇怎么玩| 欧美在线中文字幕| 国模私拍一区二区三区| 一区二区三区动漫| 亚洲激情国产精品| 中文字幕在线观看亚洲| 成人欧美一区二区三区黑人| 国外视频精品毛片| 91av在线网站| 91tv亚洲精品香蕉国产一区7ujn| 国产精品三级久久久久久电影| 久久69精品久久久久久国产越南| 亚洲激情电影中文字幕| 国产精品日韩专区| 日韩精品亚洲元码| 欧美美最猛性xxxxxx| 精品中文视频在线| 欧美激情国产精品| 九九热这里只有精品6| 亚洲免费精彩视频| 亚洲欧美精品中文字幕在线| 在线视频欧美日韩| 久久精品久久久久电影| 日本亚洲欧美成人| 九九久久精品一区| 国产在线播放91| 亚洲free性xxxx护士hd| 亚洲精品一区二区三区婷婷月| 国产欧美日韩中文字幕| 久久精品成人动漫| 亚洲一区二区久久久久久| 国产一区二区黄| 亚洲人成电影网站色www| 成人网中文字幕| 日韩大片在线观看视频| 国产精品免费一区| 2019av中文字幕| 亚洲午夜久久久影院| 欧美激情精品久久久久久黑人| 欧美高清激情视频| 中文字幕日韩高清| 精品二区三区线观看| 中文字幕精品一区久久久久| 亚洲品质视频自拍网| 亚洲第一区在线| 狠狠久久亚洲欧美专区| 亚洲欧美一区二区精品久久久| 欧美裸体xxxx极品少妇软件| 热久久视久久精品18亚洲精品| 国产欧美 在线欧美| 成人av.网址在线网站| 色综合久久88色综合天天看泰| 欧美黑人巨大精品一区二区| 欧美亚洲视频一区二区| 亚洲福利视频网| 尤物精品国产第一福利三区| 高跟丝袜欧美一区| 亚洲视频777| 日本成人在线视频网址| 久久久久九九九九| 国产精品永久免费在线| 久久精品小视频| 亚洲人免费视频| 色在人av网站天堂精品| 亚洲精品国精品久久99热一| 国产精品h在线观看| 日韩av成人在线观看| 国产精品久久久久久久久久免费| 亚洲自拍偷拍网址| 91色视频在线导航| 久久久久久噜噜噜久久久精品| 色偷偷91综合久久噜噜| 一本色道久久综合狠狠躁篇的优点| 日韩中文字幕视频| 亚洲欧美一区二区三区在线| 欧美重口另类videos人妖| 91精品久久久久久久久| 欧美日韩激情网| 91精品视频免费观看| 国产色视频一区| 欧美日韩不卡合集视频| 1769国内精品视频在线播放| 精品亚洲一区二区三区在线观看| 奇米四色中文综合久久| 亚洲sss综合天堂久久| 在线观看久久av| 欧美一区二粉嫩精品国产一线天| 成人av在线天堂| 91精品在线影院| 久久免费国产精品1| 性欧美xxxx交| 午夜剧场成人观在线视频免费观看| 国产亚洲一区二区精品| 91亚洲精品久久久久久久久久久久| 91精品在线观| 高清一区二区三区日本久| 2025国产精品视频| 成人a在线视频| 国内精品小视频在线观看| 亚州成人av在线| 日韩免费视频在线观看| 成人免费看黄网站| 国产欧美一区二区三区在线| 欧美日韩国产专区| 成人免费淫片视频软件| 国产欧美日韩免费看aⅴ视频| 久久亚洲欧美日韩精品专区| 久久精品视频va| 国产69精品久久久久久| 日韩在线视频一区| 国产在线拍偷自揄拍精品| 高清日韩电视剧大全免费播放在线观看| 亚洲а∨天堂久久精品9966| 色综合久久88| 91久久中文字幕| 国产精品亚洲网站| 亚洲美女喷白浆| 国产精品免费福利| 成人国产精品av| 亚洲激情在线观看| 中文字幕欧美亚洲| 中文字幕日韩电影| 色婷婷av一区二区三区在线观看| 日韩av三级在线观看| 欧美丰满少妇xxxxx做受| 欧美理论在线观看| 欧美激情精品久久久久久| 国内精品久久久久| 日韩中文娱乐网| 亚洲第一福利网站| 国产ts人妖一区二区三区| 精品动漫一区二区三区| 国产伦精品一区二区三区精品视频| 亚洲资源在线看|