我是新来的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;
}
我用下面的命令编译:
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
看来你认为在一秒钟睡眠之后,一秒睡眠会结束,但这并不能保证。 – Dani