2014-12-13 6 views
0

저는 Linux에서 내부 채팅을 수행하는 프로그램을 C++로 작성하고 있습니다. 코드는 개인 구조를 포함하는 클래스 속성을 가지고 있습니다.이 구조는 공유 메모리에서 초기화되므로 동일한 프로그램이 여러 터미널에서 실행되어 동일한 데이터에 액세스하고 채팅을 수행 할 수 있습니다. 제 문제는 채팅을 동시에 읽고 쓰는 것인데, 읽기 용으로 하나의 스레드를 만들고 독서 용으로 하나의 스레드를 만들어야하지만 잘 사용하는 것이 좋지는 않지만 문제가 발생합니다. 스레드를 입력하면 공유 메모리 구조에 대한 포인터가 재설정되어 주소 0x0을 가리키고 세그먼테이션 오류가 발생합니다.C++ 클래스의 스레드를 사용하는 segfault

이것은 내 프로그램이 아니지만 너무 많은 코드 줄을 넣지 않은 것입니다. 예를 들어 내가 잘못하고있는 부분을 요약했습니다. 내가 잘못하고있는 부분을 말해 줄 수 있습니까? 왜 내가 segault를 얻습니까?

#include <thread> 
#include <iostream> 
#include <mutex> 
#include <condition_variable> 

class bar { 
private: 
    struct SharedMessage{ 
    int number=21; 
    }; 

    SharedMessage* sharedMessage_; 

public: 
    void foo(void) { 
    std::cout << "hello from member function: " << std::endl; 
    std::cout << sharedMessage_->number << std::endl; 
    } 
    void thread (void){ 
    sharedMessage_=new SharedMessage; 
    std::thread t(&bar::foo, bar()); 
    t.join(); 
    std::cout << sharedMessage_->number << std::endl; 
    } 
}; 

int main() 
{ 
    bar Object; 
    Object.thread(); 
} 
+3

'bar()'대신'this'를 사용하셨습니까? –

답변

1

상황이다. sharedMessage의 포인터는 초기화되지 않으므로 sharedMessage 번호에 액세스하려고하면 세그 폴트가 발생합니다. 다른 개체를 전달하려면

std::thread t(&bar::foo, this); 

, 당신은뿐만 아니라 그것을 할 수 있지만 sharedMessage을 initalize해야 : 당신이 초기화 된 포인터를 사용하여 현재 개체를 전달하려면

, 당신은 할 수 예를 들어 클래스에 기본 생성자를 제공하면됩니다.

0

스레드에서 C++ 참조를 읽는 것부터. 막대 인스턴스를 std :: ref (bar)로 전달해야하는 것처럼 보입니다.

나는이 솔루션은 다음과 같은해야한다고 생각 :

std::thread t(&bar::foo, bar()); 

익명 bar 객체를 생성하고 스레드 사본을 전달합니다

void thread (void){ 
    sharedMessage_=new SharedMessage; 
    bar instance; 
    std::thread t(&bar::foo, std::ref(instance)); 
    t.join(); 
    std::cout << sharedMessage_->number << std::endl; 
    } 
+0

ref를 사용하여 익명의 객체를 피하는 것이 좋습니다! 그러나 나는'instance'의'sharedMessage'에 대한 포인터가 아직 초기화되지 않았기 때문에 segfault가 여전히 발생한다는 것에 대해 감사하고 있습니다. – Christophe