2017-04-21 6 views
1

I는 다음과 같이 정의 된 C++ 구조체는 다음 가지고수시 세그먼트 오류

map<string, set<Event>> mapOfEventsByString; 

하면 I가 있는지 확인하고 싶은 경우 다음과 같이

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; 

I는지도 정의한 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 시간 나는 아무 문제없이 동일한 데이터 세트 전체 응용 프로그램을 실행할 수 있다는 것을 의미)는, 여기 세그먼트 오류를 ​​얻을 수 디버깅하는 동안, 나는 그 선에 segfault를 정확히 지적했다. 해당 시나리오에서 e.id은 데이터로 채워지고 id은 "해당 값 없음"이라고 말합니다.

도움 말? 감사합니다.

+2

'mapOfEventsByString.find (aString)'이 실패 할 수 있다고 생각 했습니까? (mapOfEventsByString.end()를 돌려주는 것)? 이 경우 나머지에는 정의되지 않은 동작이 있습니다. '->'(기껏해야) 또는 다음 작업에서도 충돌 할 수 있습니다. – Scheff

+2

'typedef struct name {...} name; '은 C'ism이 아닙니다. C++에서는'typedef '가 필요 없습니다. 'struct name {...};을 가질 수 있고 C처럼'struct'로 정규화하지 않고'name'을 사용할 수 있습니다. – NathanOliver

+1

그래, 사용하기 전에 map :: find의 반환 값을 확인해야합니다.나는 당신이 "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) 
//         ^^^^^^ 

유일한 방법이

find이 실패 할 때 발생
if(mapOfEventsByString.find(aString)->second.count(event)==1) 
//         ^^ 

mapOfEventsByString.end()을 반환 : 아래의 강조 역 참조 작업이 유효하지 않은 경우 발생할 수 있습니다 (역 참조 할 수없는) :

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

나는 당신이 실제로 찾기 성공을 확인하는 경우는 것을 볼 수있을 거라 생각, 일 10 회에서, aStringmapOfEventsByString에서 찾을 수 없습니다.

는의 대신에, 이렇게하자

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

지금 당신이 때 it == mapOfEventsByString.end()에 대한 중단 점을 넣고 찾기 실패 이유 를 조사 할 수 있습니다. 행운을 빕니다!