全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1981
推到 Plurk!
推到 Facebook!

Vector容器的建構子與解構子

尚未結案
miloshop
一般會員


發表:8
回覆:22
積分:6
註冊:2004-10-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-06-13 22:05:34 IP:219.70.xxx.xxx 未訂閱
各位大大好~~我想請問一個很奇怪的問題!! 假設我有兩個CLASS, CLASS A與 CLASS B 如果class A是一個vector容器 然後我在class A裡宣告class B的指標,並且在建構子與解構子裡頭用new和delete,建立與刪除class B的記憶體位置!! 不過我發現一個很奇怪的問題!!在我在CLASS A裡建構完CLASS B時會同時進入解構子裡頭把CLASS B刪掉,因此會間接產生AV的問題!!可是如果不在解構子把這個建立的記憶體範圍剛掉,似乎又會造成程式本身的記憶體浪費!!那請教一下大大,如果遇到這種關於VECTOR容器的建構與解構要怎麼做比較好呢?? 註:CLASS A是用來存一些點集合的運算!!
GeorgeKu
中階會員


發表:1
回覆:120
積分:74
註冊:2004-10-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-06-14 12:15:44 IP:61.228.xxx.xxx 未訂閱
miloshop, 可否把你的CODE上傳或PO出來看看.
miloshop
一般會員


發表:8
回覆:22
積分:6
註冊:2004-10-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-06-14 23:23:04 IP:219.70.xxx.xxx 未訂閱
POST上來可能有點不太方便,第一是因為程式很大,約萬行左右,二是因為是論文相關的!不過大致上如下 class Boundary {   NnParameters* _Np; }; Boundary::Boundary() {   _Np=new NnParameters; } Boundary::~Boundary() {   delete _Np; } 然後在主程式裡宣告 vector Bond(3); 類似這樣子的宣告方式,當主程式建立了Bond時,會直接進入Boundary class的建構子,之後會直接進入Boundary的解構子中,所以我才覺得很奇怪,這其中有一些VECTOR的OPERATION,照裡來說在一般的CLASS裡在TRACE它的步驟時,是不會有這種情況發生的.不過好像在這裡,他會有這樣子的情況
GeorgeKu
中階會員


發表:1
回覆:120
積分:74
註冊:2004-10-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-06-15 12:57:29 IP:61.228.xxx.xxx 未訂閱
看起來這個問題因該是vector本身內部操作我們給它物件時所產生的相對動作,我想這個部分就要深入到vector內部寫作方式,才有辦法知道真正原因了. 但是就你開始所提的av問題,我想因該不是vector所造成的問題,如同你後面簡略的code去了解:
vector Bond(3);
以上的動作只是先分配3個有效的Boundary物件空間在vector容器裡,這個動作的確會對Boundary有建構跟解構的發生,但是我想這並不是間接造成av的原因,畢竟你做了以上的動作,你還是必須指派真正有效的Boundary物件到上面分配的空間,才能正確操作容器內的物件,如下:
Boundary a,b,c;
Bond[0]=a;
Bond[1]=b;
Bond[2]=c;
這是本人的淺見,如回答不好請見諒.
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-06-15 23:09:37 IP:219.84.xxx.xxx 未訂閱
miloshop你好:     vector容器包含的class需要滿足幾個先決條件。其中一個是可以物件可以正確地copy,並產生相同的物件。在你設計的class中並沒滿足,例子如下:     
 
int main(void)
{
Boundary a,b;
a = b;
}
main結束時,b的destructor呼叫馬上就會AV(重覆delete同一個物件) 相關議題,在版上已有不少文章。建議你以關鍵子"big three","copy safe","deep copy"尋找相關文章。
miloshop
一般會員


發表:8
回覆:22
積分:6
註冊:2004-10-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-06-15 23:46:17 IP:219.70.xxx.xxx 未訂閱
謝謝大大的回應,我想我還是貼上來比較快!!~~這樣子講比較容易懂 class Bound { private:         int left;         int right;         int peak;         TRect Face,_SearchE,_SearchM;         int *_pRVertPrj,*_pRHorzPrj,*_pRGradient;         friend class TFacePic;          protected:    public: .......略         NnParameter *NeuralParameters; }; Bound::Bound() { flag=false; right=-1; left=-1; NeuralParameters=new NnParameter; }; Bound::~Bound() { delete NeuralParameters; } 程式大致上如下 如果當我~Bound()裡的delete沒有註解掉的話,就會出現AV的錯誤,但是這個AV的錯誤通當是當我把FORM關掉時才會出現(有時是exception有時是直接出現AV),那由於NeuralParameters又是另一個CLASS,而裡頭也有其他的CLASS或是結構!!所以在DEBUG時我查了很久,當時去追這個CLASS的建構來源時,發現當我在執行vector的push_back的動作會有建構完直接跳入解構.我才覺得很奇怪,因為照理說解構都是當我在刪掉時才會動作吧!!所以我才猜測是VECTOR的某些東東所造成!!謝謝GeorgeKu大大的回應以及pwipwi大大的回應,在這裡的人都好熱心,有時真的不知道該怎麼給分,這兩年真的多虧有了KTOP,不然我還不知道什麼時候才能.....畢業!!哈哈~~~pwipwi大大您說的"其中一個是可以物件可以正確地copy,並產生相同的物件。在你設計的class中並沒滿足"以及"main結束時,b的destructor呼叫馬上就會AV(重覆delete同一個物件)",第兩個好像就如同我所說,在結束FORM時會發生AV,只不過我不太懂什麼叫做要正確的COPY,我先去找找大大所說的文章,不懂再請教大大!!
GeorgeKu
中階會員


發表:1
回覆:120
積分:74
註冊:2004-10-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-06-16 09:50:15 IP:61.228.xxx.xxx 未訂閱
miloshop,    你必須考慮到copy constructor的問題,當你使用vector.push_back(obj)的時候,此時obj的copy constructor會被呼叫,當離開push_back函式時候,obj的解構子會被呼叫,所以你問題是出在這裡.給你一個範例跑跑看:
#include 
#include     using namespace std;
class B{
      public:
             B(){cout<<"constructor has been called:"<<(void*)this<          
        
miloshop
一般會員


發表:8
回覆:22
積分:6
註冊:2004-10-11

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-06-16 15:22:01 IP:219.70.xxx.xxx 未訂閱
嗯,謝謝大大的回覆!!~~我有看了一下COPY SAFE跟DEEP COPY,不過找到的好像不是我要的文章A~~!!那如果現在問題點出在這裡的話,我還是有兩個問題 1. 如果這樣子的話在constructor裡寫的new NeuralParameters是不需要在destructor裡delete了嗎??是代表vector容器裡會自動安排嗎??(不加上delete在程式結束時就安全的渡過!!) 2. 其實我的目的是想要在程式結束時把這個Bound所佔有的記憶體釋放,不過如果這樣子的話,那我是要在那個地方做delete的動作呢?因為如果不做這個delete動做的話,那似乎依我所學的C ,他是會一直存在於記憶體中的吧...還是說我用VECTOR的方法原本就是個錯誤了呢?? 煩請大大們賜教 PS. Bound其實是在另一個FPIC的CLASS裡頭,所以程式有點小複雜!!
GeorgeKu
中階會員


發表:1
回覆:120
積分:74
註冊:2004-10-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-06-17 16:44:47 IP:61.228.xxx.xxx 未訂閱
你的NnParameter一定需要用動態的方式宣告嗎? 如果可以不用的話就沒有NEW跟DELETE的問題,如果必須的話,你就必須在copy constructor動手腳嚕,你應該懂copy constructor吧!我的作法會在類別裡多加一個bool flag屬性(在一般建構子裡將flag設為flase),在copy constructor裡把所有的屬性COPY一次,並且把flag設ture,在解構子裡去判斷flag,如果為flase就delete掉物件,然後如果為ture就把flag設成flase.大概方式如下:
class Bound
{
      private:
              int left;
              bool flag;
      public:
             NnParameter *NeuralParameters;
             Bound();
             Bound(Bound& obj);
             ~Bound();
};
Bound::Bound()
{
              flag=false;
              left=-1;
              NeuralParameters=new NnParameter;
}
Bound::Bound(Bound& obj)
{
                    left=obj.left;
                    NeuralParameters=obj.NeuralParameters;
                    flag=true;
}
~Bound::Bound()
{
              if(flag==false)
              delete NeuralParameters;
              flag==false;
} 
以上的code沒做過測試,僅供參考.
miloshop
一般會員


發表:8
回覆:22
積分:6
註冊:2004-10-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-06-19 00:11:11 IP:219.70.xxx.xxx 未訂閱
copy construct我不懂,不過我會去查書的!!謝謝大大不厭其煩的回答我問題,以及提供的方法~~感溫!!
miloshop
一般會員


發表:8
回覆:22
積分:6
註冊:2004-10-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-06-19 00:43:19 IP:219.70.xxx.xxx 未訂閱
我查到了!!原來是這個,謝謝大大的回覆!!
系統時間:2024-06-01 23:40:32
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!