2012-05-05 51 views
2

我在這一點上的代碼調用auto_ptr的釋放部件時,得到一個分段錯誤:段錯誤()

try 
{ 
    newMod->init(params); 
} 
catch (const std::exception& e) 
{ 
#ifndef CONFIG_STATIC 
    dlclose(handle); 
#endif 
    throw std::runtime_error(utils::buildString(
      "%s: Error initializing module %s: %s", 
      DBG_FUNC_NAME, newMod->name().c_str(), e.what())); 
} 

_modules.insert(std::make_pair(newMod->name(), newMod.release())); 

哪裏_modules是

std::map<std::string, IModule*> _modules; 

和NewMod的是

std::auto_ptr<IModule> newMod(0); 

以後用適當的指針值重新設置。我知道指向IModule的指針是有效的,因爲我在發佈之前調用init成員。

此:

_modules.insert(std::make_pair(newMod->name(), newMod.get())); 
newMod.release(); 

工作得很好,這是GDB說什麼:

#0 _M_rep (this=0xbfe8e908, __str=...) at /usr/src/debug/gcc-4.5.1-20101208/obj-i586-suse-linux/i586-suse-linux/libstdc++-v3/include/bits/basic_string.h:287 
#1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (this=0xbfe8e908, __str=...) 
at /usr/src/debug/gcc-4.5.1-20101208/obj-i586-suse-linux/i586-suse-linux/libstdc++-v3/include/bits/basic_string.tcc:173 
#2 0x0805d76f in sm::core::mod::ModuleManager::loadModule (this=0x8074768, name=..., params=...) at src/core/ModuleManager.cpp:150 
#3 0x08056edb in sm::core::Main::start (this=0xbfe8e9e0) at src/core/Main.cpp:82 
#4 0x08055131 in main (argc=4, argv=0xbfe8ebf4) at src/core/smmain.cpp:15 

,它出現segfaults上線是:

{ return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } 

什麼可以在任何想法在這個錯誤?

回答

4
_modules.insert(std::make_pair(newMod->name(), newMod.release())); 

參數的評估順序不是由標準定義的。一個實現可以在newMod->name()之前評估newMod.release(),這會使第二次調用失效。


旁註:auto_ptr被棄用C++ 11(附件D.10在草案n3290):

類模板auto_ptr已被棄用。 [注意:類模板unique_ptr(20.7.1)提供了更好的解決方案。 - 結束註釋]

如果您有權訪問該文件以及時間/資源,請考慮切換到較新的智能指針類。

+0

同意這是相當危險的,即使它現在工作,也不保證在不同的編譯器版本上工作 – EdChum

+0

好的,所以這是正確的方法嗎? '_modules.insert(std :: make_pair(newMod-> name(),newMod.get())); newMod.release();'我必須在這個中使用auto_ptr。 – Zbigh1

+0

這應該有效,是的。 – Mat