나는 문제에 관한 unordered_map도중첩 stdext :: hash_map 반복
메신저이 두 형식 정의를 사용하여이 다른 유형의 많은 컨테이너를 포함하는 SessionMap ->> SessionCharMap. 다음 m_sessions에서
이 사용됩니다
SessionMap m_sessions;
자사가 다르게 처리하는 SESSIONID 여러 subids을 지정하는 데 사용됩니다. uint32가 SessionCharMap == NULL 인 경우 계정이 아직 완전히 로그인되어 있지 않으므로 문자를 선택해야합니다. 나는 완전히 세션에 기록되지 않은에 세션에 로그인 할당 해제 할 때까지이 잘 작동 :
bool DeassignCharFromSession(uint32 acc, uint32 chr){
SessionMap::iterator itr2;
for (itr2 = m_sessions.begin(); itr2 != m_sessions.end(); itr2++){
if(itr2->first == acc){
for (SessionCharMap::iterator itr = itr2->second.begin(); itr != itr2->second.end(); itr++){
if(itr->first == chr &&
itr->second){
WorldSession* ses = itr->second;
itr2->second.erase(itr);
m_sessions[acc][NULL] = ses;
sLog.outDebug("############################################1 %d %d",itr2->first,itr->first);
return true;
}
}
}
}
return false;
}
iterration 루프가 세션이 더 이상 종료되지 않습니다 업데이트 할를 통해 실행하기 때문에 변수 내 m_sessions을 깰이 코드 심 . 나는 이미 "itr2-> second [NULL] = ses;"를 시도했다고 언급하고 싶습니다. "
2012-09-08 08:33:13 ############################################1 1 1
012-09-08 08:33:13 ########################### 123 1 0 0 0 1
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 2
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 3
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 4
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 5
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 6
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 7
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 8
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 9
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 10
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 11
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 12
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 13
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 14
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 15
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 16
2012-09-08 08:33:13 ########################### 1231 1 0
2012-09-08 08:33:13 ########################### 123 1 0 0 0 17
I 및 J 카운터 만 debugoutput입니다 :
void UpdateSessions(uint32 diff)
int i = 0;
for (SessionMap::iterator itr2 = m_sessions.begin(); itr2 != m_sessions.end(); ++itr2){
int j = 0;
for(SessionCharMap::iterator itr = itr2->second.begin(); itr != itr2->second.end(); ++itr){
//WorldSession * pSession = itr->second;
debug_log("########################### 123 %d %d %d %d %d",itr2->first,itr->first, itr->second ? 1 : 0, i,j);
j++;
WorldSessionFilter updater(itr->second);
if(!itr->second){
debug_log("########################### 1231 %d %d",itr2->first,itr->first);
//itr2->second.erase(itr);
} else
if(!itr->second->Update(updater))
{
debug_log("########################### 1233");
RemoveQueuedSession(itr->second);
debug_log("########################### 1234");
itr2->second.erase(itr);
debug_log("########################### 1235");
delete itr->second;
debug_log("########################### 1236");
}
}
i++;
}
}
는 Debugoutput에 따라 내가 얻을. j 카운터가 내부 컨테이너로 올라가는 것을 볼 수 있습니다. 그러나 나는 단 하나의 세션을 온라인으로 가지고 있습니다. 로그 아웃하려면 j가 최대 400 개의 임의의 메모리 읽기 ;-)로 바뀝니다.
은 이해 해달라고 왜의 경계에 걸쳐위한 루프
for (SessionCharMap::iterator itr = itr2->second.begin(); itr != itr2->second.end(); itr++){...}
실행됩니다. 제 생각이 틀린 실수를 발견하면 말해주십시오.
또 다른 한가지 : UpdateSession 루틴은 제대로 로그인하면 잘 작동합니다 (for-loop 당 하나의 반복 만). 오류는 먼저 로그 아웃 할 때 발생합니다. 그러면 이터레이터는 미쳐 버립니다. 내 생각 엔 DeassignCharFromSession의 컨테이너를 잘못 처리했다는 것입니다. 너희들의 도움으로
UPDATE :
수정 UpdateSession
void UpdateSessions(uint32 diff){
int i = 0;
for (SessionMap::iterator itr2 = m_sessions.begin(); itr2 != m_sessions.end(); ++itr2){
int j = 0;
for(SessionCharMap::iterator itr = itr2->second.begin(); itr != itr2->second.end();){
//WorldSession * pSession = itr->second;
debug_log("########################### 123 %d %d %d %d %d",itr2->first,itr->first, itr->second ? 1 : 0, i,j);
j++;
WorldSessionFilter updater(itr->second);
debug_log("########################### 123 %d %d %d",itr2->first,itr->first, itr->second ? 1 : 0);
if(!itr->second){
//this case should never occur!
debug_log("########################### 1231 %d %d",itr2->first,itr->first);
++itr;
//itr2->second.erase(itr);
}else
if(!itr->second->Update(updater))
{
debug_log("########################### 1233");
RemoveQueuedSession(itr->second);
debug_log("########################### 1234");
delete itr->second;
debug_log("########################### 1235");
itr2->second.erase(itr++);
debug_log("########################### 1236");
} else {
++itr;
}
}
i++;
}
}
수정 DeassignCharFromSession :
bool DeassignCharFromSession(uint32 acc, uint32 chr){
if(m_sessions[acc][chr]){
sLog.outDebug("############################################1 %d %d",acc,chr);
m_sessions[acc][NULL] = m_sessions[acc][chr];
m_sessions[acc].erase(chr);
sLog.outDebug("############################################2");
return true;
}
debug_log("################################### UUU2");
return false;
}
그러나 문제는 남아 : UpdateSessions의 루프는 unordered_map도 반복 유지합니다. 348 번 발생하고 액세스 위반으로 끝납니다. 그리고 메신저는 여전히 혼란스러워하는 이유
경우 (! itr-> 두번째) {...}
트리거. unordered_map에는 유효한 세션이 하나만 있어야하기 때문입니다.
왜 처음에 m_sessions [acc] [chr] 함수에 내장 된 hash_map 대신 2 개의 루프를 사용하고 있습니까? –
아아 멋지다 시도 할 것입니다, 그러나 그것은 내가 모든 로그인 된 세션을 반복해야하기 때문에 삭제 부분에만 작동합니다. – Dornhoeschen