亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
123下一頁
最近訪問板塊 發(fā)新帖
查看: 44906 | 回復(fù): 24
打印 上一主題 下一主題

delete一個(gè)對(duì)象數(shù)組的問題,請(qǐng)大俠幫忙看看 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2007-01-12 12:40 |只看該作者 |倒序?yàn)g覽
下面這段代碼,在Linux下用g++編譯后運(yùn)行時(shí)core dump。
請(qǐng)各位大俠看看是什么原因,多謝!


  1. #include <iostream>

  2. class Base
  3. {
  4. public:
  5.         Base () {}
  6.         virtual ~Base () {}
  7. };

  8. class Derived: public Base
  9. {
  10. public:
  11.         Derived (): i_(10) {}
  12.         virtual ~Derived () {}
  13. private:
  14.         int i_;
  15. };

  16. int main()
  17. {
  18.         Base *p = new Derived[2];
  19.         delete[] p;
  20.        
  21.         return 0;
  22. }
復(fù)制代碼

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2007-01-12 15:15 |只看該作者
up!
我也想只到為什么?

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2007-01-12 16:14 |只看該作者
Base *p = new Derived[2];

可能是編譯器在new數(shù)組時(shí),隱含了計(jì)算new出來數(shù)組大小的工作.
這樣強(qiáng)制轉(zhuǎn)換后,由于子類比基類多出一個(gè)int字節(jié), 所以在delete[]時(shí)出錯(cuò)了.

[ 本帖最后由 yulc 于 2007-1-12 16:18 編輯 ]

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2007-01-12 17:45 |只看該作者
原帖由 yulc 于 2007-1-12 16:14 發(fā)表
Base *p = new Derived[2];

可能是編譯器在new數(shù)組時(shí),隱含了計(jì)算new出來數(shù)組大小的工作.
這樣強(qiáng)制轉(zhuǎn)換后,由于子類比基類多出一個(gè)int字節(jié), 所以在delete[]時(shí)出錯(cuò)了.

那為什么delete p;就沒有問題?

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2007-01-12 17:45 |只看該作者
原帖由 happyness 于 2007-1-12 12:40 發(fā)表
下面這段代碼,在Linux下用g++編譯后運(yùn)行時(shí)core dump。
請(qǐng)各位大俠看看是什么原因,多謝!

[code]
#include <iostream>

class Base
{
public:
        Base () {}
        virtual ~Base () {}
};

class  ...
In the second alternative (delete array) if the dynamic type of the
object to be deleted differs from its static type, the behavior is undefined.73)
               --------ISO/IEC 14882:1998 5.35

程序中對(duì)象的static type為Base,而dynamic type為Derived
類型不一致,產(chǎn)生未定義行為

可以這樣做:delete [] (Derived*)p;
不過,這樣不是很好的處理方式,因?yàn)楸仨氈浪恼鎸?shí)類型

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2007-01-12 17:47 |只看該作者
原帖由 lnfxcf 于 2007-1-12 17:45 發(fā)表

那為什么delete p;就沒有問題?
In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the
static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual
destructor or the behavior is undefined.
                  --------ISO/IEC 14882:1998 5.35

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2007-01-16 10:56 |只看該作者
原帖由 lnfxcf 于 2007-1-12 17:45 發(fā)表

那為什么delete p;就沒有問題?



這個(gè)問題是根據(jù)自己的想法回復(fù)的, 不能以理服人.hehe
昨晚無意中翻開more effective c++, 找到了大師的說法:




3.3 Item M3:不要對(duì)數(shù)組使用多態(tài)
類繼承的最重要的特性是你可以通過基類指針或引用來操作派生類。這樣的指針或引用具有行為的多態(tài)性,就好像它們同時(shí)具有多種形態(tài)。C++允許你通過基類指針和引用來操作派生類數(shù)組。不過這根本就不是一個(gè)特性,因?yàn)檫@樣的代碼幾乎從不如你所愿地那樣運(yùn)行。

假設(shè)你有一個(gè)類BST(比如是搜索樹對(duì)象)和繼承自BST類的派生類BalancedBST:
class BST { ... };
class BalancedBST: public BST { ... };

在一個(gè)真實(shí)的程序里,這樣的類應(yīng)該是模板類,但是在這個(gè)例子里并不重要,加上模板只會(huì)使得代碼更難閱讀。為了便于討論,我們假設(shè)BST和BalancedBST只包含int類型數(shù)據(jù)。
有這樣一個(gè)函數(shù),它能打印出BST類數(shù)組中每一個(gè)BST對(duì)象的內(nèi)容:

  1. void printBSTArray(ostream& s,
  2. const BST array[],
  3. int numElements)
  4. {
  5.   for (int i = 0; i < numElements; ) {
  6.     s << array[i]; //假設(shè)BST類重載了操作符 < <
  7.   }
  8. }
復(fù)制代碼
當(dāng)你傳遞給該函數(shù)一個(gè)含有BST對(duì)象的數(shù)組變量時(shí),它能夠正常運(yùn)行:
BST BSTArray[10];
...
printBSTArray(cout, BSTArray, 10); // 運(yùn)行正常
然而,請(qǐng)考慮一下,當(dāng)你把含有BalancedBST對(duì)象的數(shù)組變量傳遞給printBSTArray函數(shù)時(shí),會(huì)產(chǎn)生什么樣的后果:
  1. BalancedBST bBSTArray[10];
  2. ...
  3. printBSTArray(cout, bBSTArray, 10); // 還會(huì)運(yùn)行正常么?
復(fù)制代碼


你的編譯器將會(huì)毫無警告地編譯這個(gè)函數(shù),但是再看一下這個(gè)函數(shù)的循環(huán)代碼:
  1. for (int i = 0; i < numElements; ) {
  2.   s << array[i];
  3. }
復(fù)制代碼



這里的array[I]只是一個(gè)指針?biāo)惴ǖ目s寫:它所代表的是*(array)。我們知道array是一個(gè)指向數(shù)組起始地址的指針,但是array中各元素內(nèi)存地址與數(shù)組的起始地址的間隔究竟有多大呢?它們的間隔是i*sizeof(一個(gè)在數(shù)組里的對(duì)象),因?yàn)樵赼rray數(shù)組[0]到[I]間有I個(gè)對(duì)象。編譯器為了建立正確遍歷數(shù)組的執(zhí)行代碼,它必須能夠確定數(shù)組中對(duì)象的大小,這對(duì)編譯器來說是很容易做到的。參數(shù)array被聲明為BST類型,所以array數(shù)組中每一個(gè)元素都是BST類型,因此每個(gè)元素與數(shù)組起始地址的間隔是i*sizeof(BST)。

至少你的編譯器是這么認(rèn)為的。但是如果你把一個(gè)含有BalancedBST對(duì)象的數(shù)組變量傳遞給printBSTArray函數(shù),你的編譯器就會(huì)犯錯(cuò)誤。在這種情況下,編譯器原先已經(jīng)假設(shè)數(shù)組中元素與BST對(duì)象的大小一致,但是現(xiàn)在數(shù)組中每一個(gè)對(duì)象大小卻與BalancedBST一致。派生類的長度通常都比基類要長。我們料想BalancedBST對(duì)象長度的比BST長。如果如此的話,printBSTArray函數(shù)生成的指針?biāo)惴▽⑹清e(cuò)誤的,沒有人知道如果用BalancedBST數(shù)組來執(zhí)行printBSTArray函數(shù)將會(huì)發(fā)生什么樣的后果。不論是什么后果都是令人不愉快的。


如果你試圖刪除一個(gè)含有派生類對(duì)象的數(shù)組,將會(huì)發(fā)生各種各樣的問題。以下是一種你可能采用的但不正確的做法。

//刪除一個(gè)數(shù)組, 但是首先記錄一個(gè)刪除信息
  1. void deleteArray(ostream& logStream, BST array[])
  2. {
  3.   logStream << "Deleting array at address "
  4.     << static_cast<void*>(array) << '\n';
  5.   delete [] array;
  6. }
  7. BalancedBST *balTreeArray = // 建立一個(gè)BalancedBST對(duì)象數(shù)組
  8. new BalancedBST[50];
  9. ...
  10. deleteArray(cout, balTreeArray); // 記錄這個(gè)刪除操作
復(fù)制代碼


這里面也掩藏著你看不到的指針?biāo)惴ā.?dāng)一個(gè)數(shù)組被刪除時(shí),每一個(gè)數(shù)組元素的析構(gòu)函數(shù)也會(huì)被調(diào)用。當(dāng)編譯器遇到這樣的代碼:
delete [] array;
它肯定象這樣生成代碼:
  1. // 以與構(gòu)造順序相反的順序來
  2. // 解構(gòu)array數(shù)組里的對(duì)象

  3. for ( int i = 數(shù)組元素的個(gè)數(shù) 1; i >= 0;--i)
  4. {
  5. array[i].BST::~BST(); // 調(diào)用 array[i]的
  6. } // 析構(gòu)函數(shù)
復(fù)制代碼


因?yàn)槟闼帉懙难h(huán)語句根本不能正確運(yùn)行,所以當(dāng)編譯成可執(zhí)行代碼后,也不可能正常運(yùn)行。語言規(guī)范中說通過一個(gè)基類指針來刪除一個(gè)含有派生類對(duì)象的數(shù)組,結(jié)果將是不確定的。這實(shí)際意味著執(zhí)行這樣的代碼肯定不會(huì)有什么好結(jié)果。多態(tài)和指針?biāo)惴ú荒芑旌显谝黄饋碛茫詳?shù)組與多態(tài)也不能用在一起。
值得注意的是如果你不從一個(gè)具體類(concrete classes)(例如BST)派生出另一個(gè)具體類(例如BalancedBST),那么你就不太可能犯這種使用多態(tài)性數(shù)組的錯(cuò)誤。正如條款M33所解釋的,不從具體類派生出具體類有很多好處。我希望你閱讀一下條款M33的內(nèi)容。

[ 本帖最后由 yulc 于 2007-1-16 11:00 編輯 ]

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2007-01-29 15:59 |只看該作者
一個(gè)有意義的問題,頂!!!

論壇徽章:
0
9 [報(bào)告]
發(fā)表于 2007-01-29 18:19 |只看該作者
解決辦法:
在class Base中重新定義
operator new[]和operator delete[]。

具體請(qǐng)參TC++PL 15.6節(jié)。

論壇徽章:
0
10 [報(bào)告]
發(fā)表于 2007-01-29 18:22 |只看該作者
問題加精,感謝幾位的精彩回復(fù).
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP