C++ libev回调中的列表崩溃

C++ libev回调中的列表崩溃,c++,list,crash,segmentation-fault,libev,C++,List,Crash,Segmentation Fault,Libev,我有一个libev write回调函数,它检查要发送到客户端的挂起数据。 挂起的数据缓冲区如下所示 struct PendingData{ unsigned short data_size; char data[4096]; }; typedef std::list<PendingData*> PendingBuf; class Client{ private: int sock; PendingBuf data_list; public: ev::io cl_

我有一个libev write回调函数,它检查要发送到客户端的挂起数据。 挂起的数据缓冲区如下所示

struct PendingData{
  unsigned short data_size;
  char data[4096];
};
typedef std::list<PendingData*> PendingBuf;

class Client{
private:
  int sock;
  PendingBuf data_list;
public:
  ev::io cl_io;
  void write_cb(ev::io &watcher, int events);
};
程序因分段错误而崩溃

if(!data_list.empty())
有时甚至

pd = data_list.front();
在第二种情况下,empty()返回false,但调试器显示该列表没有数据成员

它在单独的线程中运行(从同一线程读取和写入缓冲区) 我还尝试将其移动到主线程,而不启动任何其他线程,但效果相同

操作系统是Ubuntu 12.04,编译器是g++4.6
我还在我的项目中启用了c++0x

libstdc++
std::list
在c++98和c++11/c++0x模式之间不兼容。看

原因是在c++98中,不要求
std::list::size()
为O(1),而libstdc++将其实现为O(n)。在C++11中,它必须是O(1),因此在C++11模式下,在
std::list
中会出现一个额外的
size\t
成员,从而更改对象的大小

如果您的应用程序使用C++11,那么通常您链接到的所有库也应该使用C++11


编辑:抱歉,我刚刚意识到你说的是GCC4.6,它还没有修改std::list::size()所以你的问题一定是别的。

也许你在访问std::list时只需要使用锁(互斥锁) 像

//近距离列表
类客户端{
/// ...
PendingBuf数据列表;
std::互斥列表\u锁;
/// ...
}
void客户端::write_cb(ev::io&watcher,int事件){
std::锁和防护锁(列表锁);
如果(!data_list.empty()){
/// ...
}
在写入此列表时,也要使用锁。
此外,还可以使用读锁和写锁。写锁始终独占所有其他锁(读和写)。对于并发读取,可以在同一时刻多次获取读取锁。

谢谢你的回答。对不起,我对linux编程非常陌生,谷歌没有给我一个如何更改库的答案。我应该改用4.7吗?不,那没有帮助。你需要使用c++11模式重新编译libev,或者在程序中不使用c++11具有-std=c++0x的libev,但具有相同的程序行为..(仅使用libev和pthread libs)还有一点-在其他程序部分std::list没有崩溃:我怀疑新的
size\t
成员是否只存在于C++11模式中。C++11需要进行更改,但它也将在C++98模式中使用。因此,libstdc++版本之间存在二进制不兼容,而不是C++98和C++11模式之间。@MarcMutz,不,che检查上面的源代码或链接。对于c++98,libstdc++abi已经多年没有更改了。
pd = data_list.front();
// near list
class Client {
 /// ...
    PendingBuf data_list;
    std::mutex list_lock;
 /// ...
}

void Client::write_cb(ev::io &watcher, int events){
   std::lock_guard<std::mutex> lock(list_lock);
   if(!data_list.empty()){
 /// ...
}