2017-04-21 74 views
1

我有定义为C++结构如下:偶尔分段错误

typedef struct event{ 
int id; 
string name; 
//int arg0; 
QByteArray data; 

bool operator<(const event& e) const 
{ 
    return id < e.id; 
} 

bool operator==(const event& e) const 
{ 
    return id == e.id; 
} 

}Event; 

我也有一个地图定义如下:

map<string, set<Event>> mapOfEventsByString; 

当我想看看是否一个Event与给定的字符串关联我使用这行代码:

if(mapOfEventsByString.find(aString)->second.count(event)==1) 
{ 
    //do stuff 
} 

问题:在再现错误

bool operator<(const event& e) const 
{ 
    return id < e.id; <------- GIVES SEGMENTATION FAULT SOMETIMES 
} 

多次尝试后:有时候,(我的意思是说9月10日的时候,我可以运行完全相同的数据集的整个应用程序没有任何问题),我得到一个分段错误这里在调试的同时,我设法找出了该段的段错误。在这种情况下,e.id填充了数据,id表示:“没有这样的值”。

帮助? 谢谢

+2

你考虑(是否有可能)是'mapOfEventsByString.find(ASTRING)'可能会失败(即返回'mapOfEventsByString.end()')?在这种情况下,其余的有未定义的行为。它可能会在' - >'(最好)甚至在下面的操作中崩溃。 – Scheff

+2

不要说'typedef struct name {...} name'是C'ism。在C++中,不需要'typedef'。你可以只'结构名{...};'和'使用不name'和'struct'限定它就像你C. – NathanOliver

+1

呀,你必须检查地图的返回值::发现在使用它之前。我怀疑你使用的是“typedef”,表示你来自C国,这可能就是为什么你试图把所有东西都压缩到一条线上的原因。我建议你用多行来做,例如auto eventKey = mapOfEventsByString.find(aString); if (eventKey != mapOfEventsByString.end() {if (eventKey->second.count(event)==1) {//do stuff}}或者,使用map :: get,把你的电话放在一个try块中,并捕获out_of_range。 – tipaye

回答

0

没有回溯我们只是猜测,但这是一个强烈的迹象表明,成员id不存在,所以你正在访问你不应该的内存。

如果成员id不存在,那么你的operator<电话坏了。由于它是由你的代码的下面突出的部分调用:

if(mapOfEventsByString.find(aString)->second.count(event)==1) 
//           ^^^^^^^^^^^^^ 

该建议,我认为下面的突出表达不确实指向一个合法的对象:

if(mapOfEventsByString.find(aString)->second.count(event)==1) 
//         ^^^^^^ 

的唯一方式可能发生的是,如果下面的高亮取消引用操作是无效的:

if(mapOfEventsByString.find(aString)->second.count(event)==1) 
//         ^^ 

find失败发生,返回mapOfEventsByString.end() (不能解除引用):

if(mapOfEventsByString.find(aString)->second.count(event)==1) 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

我认为,如果你真的检查发现的成功,你会看到,1出10倍,aString不是在mapOfEventsByString找到。

让我们做到这一点,而不是:

const auto it = mapOfEventsByString.find(aString); 
if (it != mapOfEventsByString.end() && it->second.count(event) == 1) { 
    // do stuff 
} 

现在你可以把一个断点在当it == mapOfEventsByString.end(),并调查为什么查找失败。祝你好运!