2013-10-23 22 views
0

我正在摸索着這個問題。如果只有我能夠看到它或者是一個晦澀難懂的問題,那麼這是一個真正簡單的答案。問題是我在一個函數中新建一個struct對象,將指針保存到一個出列,在另一個func中檢索該指針,然後一旦結構的數據被使用,試圖刪除堆上的對象。一切都發生在一個類實例中。當這樣做,我得到da炸彈。我無法弄清楚爲什麼。這是創建和檢索後的有效指針。我可以寫/讀它。但是當試圖刪除它時,我得到了da炸彈刪除導致有效結構指針中斷

//This creates and saves the heap object 
void CFoo::QueueEvent(TICKTYPE& tp) 
{ 

    TICKTYPE* pTt = new TICKTYPE; 

    memcpy(pTt, &tp, sizeof(tp)); 

    m_queuedevents.push_front(pTt); 

} 

//This retrieves it 
int CFoo::ReplayQueuedEvents() 
{ 
    long lSz = m_queuedevents.size(); 

    for(int i = 0; i < lSz; i++) 
    { 
     TICKTYPE Tt; 

     TICKTYPE* pTt = m_queuedevents.back(); 
     //m_queuedevents.pop_back(); //bombs w or w/o this 

     //bombs w ot w/o memcpy 
     memcpy(&Tt, pTt, sizeof(*pTt)); 

     //int iRtn = SendEvent(Tt); 

     ASSERT(SendEvent(Tt) != ERR_FAILURE); 

     //This asserts before or after the memcpy. 
     delete[] pTt; 
     //delete pTt; 

    } 

}

PART 2

謝謝大家的建議。

刪除[] VS刪除

我很絕望,所以我嘗試刪除[]過,並且正好是我複製了一個。我試過在兩個地方刪除,仍然得到的行爲。

「顯示滾動類型」

我會顯示滾動類型,但現在,我看它它被相當簡單,與它內部的其他至少2層結構的引用相當複雜的成長。我不得不張貼(和格式)幾頁的代碼。根據下面的評論,我會試着把它當作崩潰的來源。謝謝。

「在刪除它之前檢查pTt ia是否有效。」

我試過在讀取和寫入之前刪除和所有似乎確定。此外,Vis Stud在刪除前在結構中顯示有效數據。隨着我進一步研究,我會記住這一點。

「規則三」

嗯,這很好,可能是這種情況。

我還沒有解決方案,但是當我這樣做時我會回覆。你們都提供了一些好點子,我不再撓頭了。只是膝蓋深處工作。敬請期待...

再次感謝。 (PS'da bomb'通常是一件好事,但英語的美妙之處在於你可以說出自己的想法並且仍然能夠理解'更精確但無聊的術語應該是GPF,ASSERT等。我在交易時需要這些東西用C++有時... :)沒有一個關於編碼here..lol的心理永遠會談。「)

PART 3

原來,問題出在memcpy的,如果我拿出所有的我需要從參考TICKTYPE & tp到指針TICKTYPE * pTt(請參閱QueueEvent)

我試圖創建一個複製構造函數,每個很酷的sugge如下所示。如果傳統的拷貝構造函數使用諸如

問題返回
TICKTYPE(TICKTYPE const& ref) 
{ 
    a = ref.a; 
    b= ref.b; 
    c = ref.c; 
    d= ref.d; 
    e = ref.e; //etc... 
} 

有一對夫婦的主結構內部結構是那些獲得深複製的,另外還有一些MSFT結構FILETIME和SYSTEMTIME,我不知道他們已經有副本或沒有。

然後有從ref到ptr的問題。我嘗試了一個帶簽名的複製ctor

TICKTYPE * ref;

然後

PTT = RTT

其中PTT的滾動類型*和RTT是滾動類型RTT。這沒有編譯。

問題

什麼是複製包含從裁判其它結構的新指針VAR(從堆棧堆)一個結構的最佳方式。我想將這些數據從棧中移到堆中以獲得更多的永久存儲。

我正在考慮做每個結構級別的mem副本,以免由memcpy複製的結構將嵌入struts。你怎麼看?好的方法?

PART 4

再次感謝所有回覆的人。你的建議非常有幫助。該問題是在執行頂級結構的memcpy時創建的。在主頂層結構中執行從屬結構的memcpy,只要它們不具有從屬結構,不會導致delete失敗。我在頂層結構上通過變量副本對下級結構和變量使用memcpy。它看起來是這樣的

TYPE1 foo1; 

foo1.a = foo.a 
foo1.b = foo.b 
foo1.c = foo.c 
memcpy(foo1.d, foo.d, sizeof(foo.d)); 
memcpy(foo1.e, foo.e, sizeof(foo.e)); 

工程。它可能不像其他一些方法那麼優雅,但它的工作原理或似乎暫時存在,而且它在主要代碼體中都有明確的記錄,發生了什麼,因此它有其好處。

+0

顯示滾動類型的定義。 –

+0

當有更精確的技術術語可用時,請勿使用類似「da bomb」的短語。 – templatetypedef

+0

你已經清楚地註釋了兩條'delete'行中錯誤的行。什麼類型是'm_queuedevents'? –

回答

4

delete[] pTt;導致未定義的行爲,因爲您將其分配給new而不是new[]。使用delete

如果你已經嘗試過,很可能你沒有遵守三條規則(谷歌它)。 memcpy(&Tt, pTt, sizeof(*pTt));可能會跨本地TtpTt傳播某些資源的所有權。當Tt超出範圍時,將調用其析構函數。然後當你調用delete時,析構函數爲pTt。如果析構函數試圖釋放相同的資源,您將會遇到崩潰。

在這種情況下請勿使用memcpy。使用複製構造函數。

TICKTYPE Tt = *pTt;