2014-02-24 75 views
3

我有一個類(我們稱之爲「Common」),用於創建定時器並從另一個類調用成員函數(讓我們稱之爲「A」),當定時器到期。 一般的想法是這樣的: - A從Common調用一個函數,通過它傳遞一個指向將在定時器到期時執行的成員函數的指針 - Common將指針指向映射中的函數並帶有定時器ID爲 - 當定時器命中時,搜索地圖匹配鍵,然後調用相關的函數。函數回調使用std :: bind導致分段錯誤

這裏是代碼答:

void A::setTimer() 
{ 
    std::function<void(void)> handler = std::bind(&A::onEventFunc, this); 
    pCommon->scheduleTimer(&handler); 
} 

onEventFunc是A類的公共職能的計時器到期時,做的東西。

下面是常見的代碼:這一切都編譯

static void timerHandler(int sig, siginfo_t *si, void uc) 
{ 
    map<timer_t*, std::function<void>(void)>*)::iterator iter = 
           globalTimerMap.find((timer_t*)si->si_value.sival_ptr); 
    if (iter != globalTimerMap.end) 
    { 
     std::function<void>(void)>* handler = iter->second; 
     (*handler)(); 
    } 
} 

Common::schedulerTimer(std::function<void>(void)* handler) 
{ 
    // uses Linux timer_create and timer_settime 
    // code for these excluded EXCEPT the relevant lines 
    sa.sa_sigaction = timerHandler; 

    // bunch of other code here for timer_create and timer_settime 

    // insert into map 
    globalTimerMap.insert(pair(&timerid, handler); 
} 

,直到它擊中(*處理器)上運行得很好();給出分段錯誤的線。

我是新來的推動和Linux編程,以及我在C++上的任何知識都是從工作培訓中獲得的。這使我相信我正在做一些非常愚蠢/愚蠢的事情,但我只是不知道它是什麼。我試圖做什麼甚至應該工作?

回答

5

以下行:

std::function<void(void)> handler = std::bind(&A::onEventFunc, this); 

這在棧上的局部變量(您的本地setTimer成員函數)。這意味着你的地圖中的指針都指向無效的內存。

我會改變你的地圖存儲實際std::function對象,而不是指針。 如果你堅持在地圖中存儲的指針,你將需要動態分配內存,使內存仍然有效:

std::function<void(void)>* handler = new std::function<void()>(std::bind(&A::onEventFunc, this)); 

但是,你會再需要delete內存以避免內存泄漏,所以另一種選擇是在你的地圖中使用std::unique_ptr來處理這個問題。

+0

謝謝!按照你的建議,我改變了地圖以保存std :: function,現在它可以工作。我知道我在做一些非常愚蠢的事情。所以問題是,當它在堆棧上創建「處理程序」,然後使用指針時,它指向什麼都沒有,因爲「處理程序」在函數退出時被銷燬。 – user3348501

+0

@ user3348501:是的,那正是發生的情況。不錯的工作! –