2011-04-04 47 views
1

感謝您查看我的問題。C++ new()在調用ctor之前崩潰了

我有一個對象正在我的程序中動態創建。創建是循環的一部分,第一次迭代工作正常。

創建時,我的對象基類將自己添加到地圖中。

下面是一些示例代碼:

public class Base { 
    Base() { 
     // Add itself to a map 
     Data::objects[key] = this; 
    } 
} 

public class Derived : public Base { 
    // This ctor only initialize one int field. 
    Derived() : Base() {}; 
} 

還挺簡單的,不是嗎?

在我的代碼中,我做了Derived * d = new Derived();,出於某種愚蠢的原因,我得到了一個SIGSEGV。

我試着去調試它,但是它甚至沒有在崩潰前進入ctor!

這裏是我的調用堆棧,所以你可以幫助我更好:

地址:!@ 0x002c0000
NTDLL RtlReleasePebLock()
地址:@ 0x0000000c在C:\ stl_deque.h:514 !
msvrct的malloc()
的libstdC++ - 6 _Znwj()
fu87 _ZSt4cerr(此= 0xbc1ad8,E = 「//我的對象名//」)在我的//對象名稱// CPP
...其他是我的線。

謝謝,米卡埃爾

{}享受

編輯:添加信息關於地圖

地圖坐落在一個數據類,靜態。

// Data.h 
class Data { 
    static map<int, Base*> objects; 
} 

// Data.cpp 
#include "Data.h" 
map<int, Base*> Data::objects; 

// methods implementations 

你怎麼能腐化堆,我怎麼能找到腐敗發生?

+7

'map'定義在哪裏?這類問題往往表明你已經損壞了堆;不幸的是,這種問題可能直到它發生之後纔會出現。這個問題可能與您的代碼完全無關。你能整理一個相對較小的示例程序來證明問題嗎? – 2011-04-04 16:33:57

+1

順便說一句,正確的術語是「派生」,而不是「派生」;-) – fredoverflow 2011-04-04 16:40:57

+0

您是否從頭中刪除了未使用的函數或變量?你有沒有嘗試清理和重建? – 2011-04-04 16:51:47

回答

2

在創建任何使用Base之前,是否已初始化Data::objects

只要您在最終鏈接目標中有多個翻譯單元(請閱讀.cpp文件),就不能保證類對象objects已經初始化,除非您特別努力確保它。

大多數人通過使用一個靜態類來解決這個問題,通過這個類可以保證初次使用時的初始化。例如:

// untested code, typed in by hand, not compiled through a machine compiler. 
class Base { 
    public: static addObject(Base* that); 
    Base::Base() { Base::addObject(this); } 
}; 
class Derived: public Base { 
    Derived::Derived() {} 
}; 
// 
// and in the .CPP for Base 
namespace /* hidden */ { 
    int object_number = 0; 
    map<int,Base*> *objects = NULL; 
} 
void Base::addObject(Base* that) { 
    // TODO: do something to avoid multi-thread issues if that is ever a concern 
    if (!objects) { 
     objects = new map<int,Base*>(); 
    } 
    (*objects)[++object_number] = that; 
} 
+0

這是一個很好的觀察,但是該映射不是指針類型,並且在.cpp文件中初始化。 – 2011-04-04 19:32:58

+0

雖然它應該已經初始化(AFAIK它應該自動執行),但錯誤消失了。謝謝您的回答。 – 2011-04-04 19:45:08

+0

僅僅因爲它是在.cpp文件中初始化的,並不意味着它在剛剛創建的* first *對象被初始化之前恰好使用它。 – 2011-04-04 22:47:14

2

您可能在分配之前的某個時刻損壞了堆,導致崩潰。嘗試使用valgrind運行以查看您的出錯地點

+0

不幸的是,我正在研究Windows 7環境,因爲它只能在Linux上運行,所以我不能使用Valgrind。這是我唯一的選擇嗎?我應該使用虛擬機來運行它嗎? – 2011-04-04 17:06:45

+1

虛擬機?我的媽呀!只需發佈導致問題的代碼即可。所有這些(但儘可能小,你可以做到)。 – TonyK 2011-04-04 17:10:02