2017-04-21 60 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(),並調查爲什麼查找失敗。祝你好運!