2016-07-07 2 views
-1

내가 USACO 교육 페이지에서 문제 중 하나가 코딩 된의 삽입 기능에 액세스를 시도하고 내 코드를 디버깅하려고 할 때 때 : 나는 "ANDY 해리"를 입력하려고 할 때0xC0000005 : 0x00000000 위치를 실행하는 액세스 위반. multimap은

#include <iostream> 
#include<fstream> 
#include<string> 
#include<map> 
#include<math.h> 
using namespace std; 
int translate(string &s) { 
    int n = s.length(); 
    int result = 0; 
    for (int i = 0; i < s.length(); i++) { 
     int n1 = 0; 
     if (s.at(i) == 'Q' || s.at(i) == 'Z') { 
      return -1; 
     } 
     switch (s.at(i)) { 
     case 'A': 
     case 'B': 
     case'C': 
      result = result + 2 * pow(10, n-1); 
      n--; 
      break; 
     case 'D': 
     case 'E': 
     case'F': 
      result = result + 3 * pow(10, n - 1); 
      n--; 
      break; 
     case 'G': 
     case 'H': 
     case 'I': 
      result = result + 4 * pow(10, n - 1); 
      n--; 
      break; 
     case 'J': 
     case 'K': 
     case 'L': 
      result = result + 5 * pow(10, n - 1); 
      n--; 
      break; 
     case 'M': 
     case 'N': 
     case 'O': 
      result = result + 6 * pow(10, n - 1); 
      n--; 
      break; 
     case 'P': 
     case 'R': 
     case 'S': 
      result = result + 7 * pow(10, n - 1); 
      n--; 
      break; 
     case 'T': 
     case 'U': 
     case 'V': 
      result = result + 8 * pow(10, n - 1); 
      n--; 
      break; 
     case 'W': 
     case 'X': 
     case 'Y': 
      result = result + 9 * pow(10, n - 1); 
      n--; 
      break; 
    } 
    } 
    return result; 
} 
bool mycompare(int n, int m) { 
    string a, b; 
    a = to_string(n); 
    b = to_string(m); 
    if (a < b) { 
     return true; 
    } 
    else return false; 
} 
int main() { 
    bool(*ptr)(int, int); 
    typedef multimap<int, string, bool(*)(int, int)> mmid; 
    mmid pairs(ptr); 
    string s1; 
    ifstream inFile("dict.txt", ios::in | ios::binary); 
    while (cin>>s1) { 
     int f =translate(s1); 
     pairs.insert(mmid::value_type(f, s1)); 
    } 
    int m; 
    cin >> m; 
    multimap<int, string>::iterator it; 
    while (true) { 
     it = pairs.find(m); 
     if (it != pairs.end()) { 
      cout << it->second << endl; 
      pairs.erase(it); 
     } 
     else { 
      break; 
     } 
    } 


    return 0; 
} 

을, 그것은이 라인에서 두 번째 항목에

pairs.insert(mmid::value_type(f, s1)); 

를 처리 할 때 그것은 나에게가 0xc0000005의 코드를 제공합니다 : 위치를 0x00000000을 실행 액세스 위반을. 내 코드에 어떤 문제가 있습니까? 그리고 그것은 왜 나에게 첫 번째 엔트리가 아니라 두 번째 엔트리에 에러 메시지를 주는가? 감사. 첫 번째 줄에서

bool(*ptr)(int, int); 
mmid pairs(ptr); 

, 당신은 ptr라는 이름의 함수 포인터를 정의하지만 당신은 초기화되지 않은두고 :

+2

표준 비교 개체를 대체하기 때문에 비교 대상을 어디에서 설정합니까? – NathanOliver

+2

"내 코드를 디버그하려고했을 때"- 디버그보다는 실제로 _test_를 사용하는 것처럼 들립니다. 글쎄, 이제 당신의 테스트가 _bug_을 밝혀 냈습니다. 그래서 당신은 그것을 알아야합니다. 디버깅하는 방법은 디버거를 사용하는 것입니다! 하나는 실패 후 (또는 임의의 중단 점에서) 스택 추적을 실행하여 문제에 이르는 함수의 정확한 호출 체인을 볼 수 있고 거기에서 그 원인을 식별 할 수 있습니다. 디버거를 사용해 보셨습니까? –

+1

왜 프로그램 끝 부분에 무한한 while 루프가 있습니까? – PaulMcKenzie

답변

2

나는 문제가이 코드에 생각합니다. 즉 pairsptr으로 초기화하면 가비지 비교 함수 포인터로 초기화됩니다.

이 문제를 해결하려면 사용하려는 실제 비교 함수를 전달하십시오. 예를 들면 다음과 같습니다 또한

mmid pairs(mycompare); 

,이 코드는 매우 의심스러운 :

multimap의 유형 pairs의 유형과 일치하지 않습니다, 그래서 이것은 의심 할 선험적 인 이유가 없다는 것을
multimap<int, string>::iterator it; 
it = pairs.find(m); 

공지 사항 반복자가 올바르게 작동합니다. 대신 다음을 고려하십시오.

mmid::iterator it; 
+0

OP를 명확히하기 위해,이 경우에는 포인터가 0 인 경우, null 포인터가 될 수 있지만, 아무 것도 될 수는 없습니다. - unitialised 변수를 읽는 것이 정의되지 않은 동작이기 때문입니다. 덧글에서 마지막 질문에 대한 나의 대답을 반복하기 위해서 :'map()'은 비교할 필요가 없기 때문에 이것은 첫 번째'insert()'에서 발생하지 않는 이유입니다. –

+0

내가 제안한대로 코드가 변경되어 작동했습니다. 고맙습니다. – harry47341