私はC++を初めて使用しています。なぜ次のコードにセグメンテーションフォールトがあるのかわかりません。 Doo()は、マップ<>を含むクラスです。 Doo :: start()を呼び出してwhileループスレッドを開始することができます。その後、Doo :: turnoff()を呼び出してスレッドを終了します。自分のコードに何が間違っているのか分かりません。私の理解を助けてください。次のコマンドでコンパイルさセグメンテーションフォルト、考えられる理由:関数ポインタ、マルチスレッド、stlマップなど
#include <iostream>
#include <thread>
#include <map>
#include <chrono>
using namespace std;
class Doo{
int id;
bool _turnoff=false;
map<int,string> msg;
public:
Doo(int _id);
void start(bool (*fptr)(map<int,string>&));
void turnoff();
};
Doo::Doo(int _id){
id = _id;
msg[1]="hello";
msg[2]="nihao";
msg[4]="conichiwa";
}
void Doo::start(bool (*fptr)(map<int,string>&)){
thread m_thr([&](){
while(!_turnoff){
this_thread::sleep_for(chrono::seconds(1));
fptr(msg);
}
});
m_thr.detach();
}
void Doo::turnoff(){
_turnoff=true;
}
bool hdl(map<int,string>& greet){
cout<<greet[2]<<endl;
return true;
}
int main(void){
Doo d(1);
d.start(hdl);
while(1){
char x;
cin>>x;
if(x=='q'){
cout<<"quit"<<endl;
d.turnoff();
this_thread::sleep_for(chrono::seconds(1));
break;
}
}
return 0;
}
I:それは問題なくコンパイル
g++ p3.cpp -std=c++11 -pthread
。
valgrindの結果:
==18849== Memcheck, a memory error detector
==18849== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18849== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18849== Command: ./a.out
==18849==
==18849==
==18849== Process terminating with default action of signal 11 (SIGSEGV)
==18849== Bad permissions for mapped region at address 0x68C1700
==18849== at 0x68C1700: ???
==18849== by 0x402799: void std::_Bind_simple<Doo::start(bool (*)(std::map<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&))::{lambda()#1}()>::_M_invoke<>(std::_Index_tuple<>) (in /home/xli1989/Projects/playground/a.out)
==18849== by 0x4026EF: std::_Bind_simple<Doo::start(bool (*)(std::map<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&))::{lambda()#1}()>::operator()() (in /home/xli1989/Projects/playground/a.out)
==18849== by 0x40267F: std::thread::_Impl<std::_Bind_simple<Doo::start(bool (*)(std::map<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&))::{lambda()#1}()> >::_M_run() (in /home/xli1989/Projects/playground/a.out)
==18849== by 0x4EF2C7F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==18849== by 0x53D96F9: start_thread (pthread_create.c:333)
==18849== by 0x56F5B5C: clone (clone.S:109)
ルールが破られることはありませんが、その前にルールが存在することを確認することをお勧めします。 [C++識別子でアンダースコアを使用する際の規則は何ですか?](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier) – user4581301
あなたは1秒の睡眠が早い1秒の睡眠の後に終了すると仮定しているようですが、それは保証されていません。 – Dani