2010-06-10 45 views
0

//非單 類MyLogManager { 空隙寫(消息){食人魔::日誌管理:: getSingletonPtr() - >的LogMessage(消息);}} 段錯誤與單身

class Utils : public singleton<Utils> 
{ 
    MyLogManager *handle; 
    MyLogManager& getHandle { return *handle; } 
}; 

namespace someNamespace 
{ 
    MyLogManager &Log() { return Utils::get_mutable_instance().getHandle(); } 
} 

int main() 
{ 
    someNamespace::Log().write("Starting game initializating..."); 
} 

在這種代碼我使用boost的singleton(從序列化)並調用Ogre的日誌管理器(它也是單例類型)。

程序在任何試圖做一些與食人魔::日誌管理:: getSingletonPtr()對象的代碼

User program stopped by signal (SIGSEGV)

我檢查了getSingletonPtr()返回地址不能量0x000

但是使用代碼Utils::get_mutable_instance().getHandle().write("foo")在程序的另一部分工作良好。在打電話給單身人士時可能會出現什麼問題?


的Utils類的現實版:

class Utils : public singleton<Utils> 
{ 
    protected: 
     ConfigManager *configHandlePtr; 
     LogManager *logHandlePtr; 

    public: 
     Utils() 
     { 
      configHandlePtr = new ConfigManager(); 

      string engineLog = configHandle().getValue<string>("engine.logFilename", "Engine.log"); 
      logHandlePtr = new LogManager(engineLog); 
     } 
     ~Utils() 
     { 
      delete configHandlePtr; 
      delete logHandlePtr; 
     } 

     ConfigManager &configHandle() const { return *configHandlePtr; } 
     LogManager &logHandle() const { return *logHandlePtr; } 
}; 

這裏是真正的代碼的LogManager類:

class LogManager 
{ 
    protected: 
     string mDefaultPath; 

    public: 
     LogManager(const string &logPath = "Engine.log") : 
       mDefaultPath(logPath) { } 

     void write(const string &message, const string logFile = "") 
     { 
      string workPath = mDefaultPath; 


      Ogre::LogManager *logHandle = Ogre::LogManager::getSingletonPtr(); // [logHandle=0x000] 
      Ogre::Log *log2Handle = logHandle->getLog(workPath); // [SEGFAULT] 
      log2Handle->logMessage(message); 

      Ogre::LogManager::getSingletonPtr()->logMessage(message); 
     } 
}; 

UPDATE:

我有一個靜態庫(在那裏我是我的引擎代碼)和鏈接靜態庫的主要自己的程序。當我打電話給我的配置句柄(不使用Ogre)時,一切都好!還有resourceManager,它也使用Ogre。並且它像logManager那樣失敗。這兩位經理都使用Ogre的單身人士。也許從另一個庫中調用它是不可能的?

+0

初始化在這裏至關重要。 – 2010-06-10 14:53:17

+0

@ konrad-rudolph代碼已更新 – Ockonal 2010-06-10 15:03:54

+0

您的應用程序是多線程的嗎? – Alerty 2010-06-10 15:09:12

回答

1

這種感覺就像你有典型的「static initialization order fiasco」 - 先於其他單身的一方(或雙方)的utils的實例創建的。

嘗試改變的Utils :: configHandle()來是這樣的:

ConfigManager &configHandle() const { 
    static std::auto_ptr<ConfigManager> configHandlePtr(0); 
    if (!configHandlePtr.get()) { 
     configHandlePtr.reset(new ConfigManager()); 
     // init configHandlePtr like you want 
    } 
    return *configHandlePtr; 
} 
0

我不知道Boost的單身人士,但我注意到'Utils'類中有些奇怪的東西。

首先,getHandle返回引用來處理,但處理是一個局部變量超出範圍,如果你離開的方法,所以對它的引用也將是無效的。

其次,您沒有在getHandle方法中初始化句柄。

+0

有打字錯誤,sory。我返回'*手柄'。而且我特別沒有編寫** getHandle **初始化來使代碼更清晰。 – Ockonal 2010-06-10 14:42:11

0

你確定你的Ogre LogManager被正確初始化了嗎?

或者也許與你的庫你有每個庫中的單例的一個實例,只有主程序中的一個正確初始化?

在這種情況下,您必須將庫中的單例聲明爲「extern」,但我不確定它適用於靜態鏈接庫。

+0

是的,它在另一部分代碼中很有用。請注意,在更新。 – Ockonal 2010-06-10 15:04:16