2016-12-01 68 views
0

我有下面的代碼來獲取核心轉儲錯誤。每個C實例創建自己的線程然後運行。我猜靜態函數和類參數「count」有問題。當我註釋掉打印它的代碼時,沒有發生故障。在類中使用pthreads時出現分段錯誤

#include <iostream> 
    #include <pthread.h> 
    using namespace std; 

    class C { 
     public: 
     int count; 
     C(int c_): count(c_){} 
    public: 
     void *hello(void) 
     { 
      std::cout << "Hello, world!" <<std::endl; 
      std::cout<<count; // bug here!!! 
      return 0; 
     } 

     static void *hello_helper(void *context) 
     { 
      return ((C *)context)->hello(); 
     } 

     void run() { 

      pthread_t t; 
      pthread_create(&t, NULL, &C::hello_helper, NULL); 
     } 

    }; 

    int main() { 

    C c(2); 
    c.run(); 

    C c2(4); 
    c2.run(); 

    while(true); 

    return 0; 
    } 

回答

1

決定寫一個答案。你打電話hello_helpercontextNULL根據你如何創建你的線程。 C++完全允許您在空指針上調用成員函數,除非訪問成員元素,否則不會發生錯誤。

在你的情況下,通過添加行打印count。你現在正在訪問一個空指針的成員變量,這是一個很大的禁忌。

這裏是你就要用什麼樣的例子:

#include <iostream> 
class Rebel 
{ 
    public: 
    void speak() 
    { 
     std::cout << "I DO WHAT I WANT!" << std::endl;   
    }  
}; 
int main() 
{ 
    void * bad_bad_ptr = NULL; 
    ((Rebel*)bad_bad_ptr)->speak(); 
} 

輸出:

I DO WHAT I WANT!

通過修改您的pthread_create調用以傳遞this指針(即pthread_create(&t, NULL, &C::hello_helper, this);,你現在有一個有效的實例來訪問成員變量。

+0

mascoj你是對的,那個參數是指向一個類實例的指針,我當時馬虎不在。 。 – eral

-1

我通過在創建線程時將此指針傳遞給NULL來解決此問題。我猜os在前一種情況下創建了兩次相同的線程?

+1

不,你正在調用''''hello_he ''''''''''NULL''''的背景..... – mascoj

+0

爲什麼這麼重要?當我不打印計數變量時,這是可以的。 – eral

+0

爲了使這個答案更有用(並且減少了誘餌誘餌),我建議添加你改變的代碼,改變它的代碼,並解釋如何解決你的問題。 – user4581301