2014-04-27 2 views
0

해시 테이블을 직접 프로그래밍하고 있습니다. 이 프로젝트의 경우 데이터를 저장하는 테이블 인 std::list 배열이 있습니다. 모든 목록은 std::pair 개의 개체로 구성됩니다. 쌍에는 std::string (사람의 이름)과 사용자 지정 클래스 (해당 사용자에 대한 데이터가 들어있는 클래스)의 개체에 대한 포인터가 포함되어 있습니다.std :: string 및 사용자 정의 객체를 std :: pair에 저장

해시 테이블에 데이터를 삽입하기위한 put() 메서드 구현에 문제가 있습니다. 이것이 제가 작성한 코드입니다.

pair<string,StudentRecord*>* HashTable::put(string& p_Name, StudentRecord* p_StudentRecord){ 


    std::pair<std::string, StudentRecord*> ptr = { p_Name, p_StudentRecord }; 
    this->put(&ptr); 
    return &ptr; 
} 

void HashTable::put(pair<string, StudentRecord*>* p_HTElement){ 

    string key = p_HTElement->first; 
    int storage_place = this->m_Hasher->hash(key) % this->m_Capacity; 
    this->m_Table[storage_place].push_back(p_HTElement); 
    this->m_NumberOfEntries++; 
    this->updateLoadFactor(); 

    if (this->m_LoadFactor >= MAX_LOAD_FACTOR) 
     this->rehash(); 
} 

데이터를 추가해야하는 경우 첫 번째 방법이 호출됩니다. 이 메서드는 std::pair 개체를 만들고이 개체에 대한 참조를 두 번째 메서드로 전달합니다. 그런 다음 두 번째 방법은 해시를 계산하여 std :: list 배열에 저장합니다. 그러나 문제는 배열에 넣어 후 std::string (쌍의 첫 번째 요소) 더 이상 읽을 수 없다는 것입니다. 디버거를 살펴보면 값이 ""라는 것을 알 수 있습니다. 나중 단계에서 해시 테이블의 데이터를 찾으려면 printHashTable() 메서드가 해당 목록을 인식하지만 데이터를 읽을 수 없습니다. 다시 디버거는 한 쌍의 첫 번째 요소와 그것이 말하는 사용자 정의 개체에 대한 문자열

오류 읽기 문자를 말한다 0xccccccccc

이 인쇄 할 필요가 내 방법입니다 해시 테이블의 모든 데이터 :

void HashTable::printTable(){ 
    for (int i = 0; i < this->m_Capacity; i++){ 
     if (!this->m_Table[i].empty()) { 
      for (std::list<std::pair<std::string, StudentRecord*>*>::iterator element = this->m_Table[i].begin(); element != this->m_Table[i].end(); ++element) { 
       cout << (*element)->first << endl; 
      } 
     } 
    } 
} 
+0

회원 변수의 유형은 무엇입니까? – tillaert

+0

로컬 변수에 대한 포인터를 반환 중 ... –

+0

맞춤 클래스의 멤버 변수 StudentRecord? 학생 기록은 단지 std :: string과 int 변수로 구성됩니다. @MarcGlisse 알겠습니다. 그러나 새로운 쌍 객체를 만들어야하고 put() 메서드 내에서 만들 수없는 경우 어떻게해야합니까? –

답변

1

개체 참조에 대한 포인터를 저장합니다. 그러나 첫 번째 함수를 떠날 때 그 객체는 참조 해제되므로 테이블은 초기화되지 않은 메모리를 가리 킵니다. 포인터를 사용하여 데이터를 저장하지 말고 emplace 메서드를 사용하여 복사본을 만들지 마십시오.

std::list<std::pair<std::string, StudentRecord*>*>은 가리키는 개체를 소유하지 않으므로 포인터 만 사용합니다.

당신은 사본을해야, 당신은으로 유형을 변경하여 적용 할 수 있습니다 :

std::list<std::pair<std::string, StudentRecord*>>

당신은 내가 그것이 무엇인지 볼 수 없습니다 귀하의 예제에서,뿐만 아니라 당신의 m_Table 유형에 적응해야합니다

. 그런 다음 포인터를 유지하려면

, 당신은 대신 스택의 힙에 객체를 할당 할

std::pair<std::string, StudentRecord*> ptr = { p_Name, p_StudentRecord };

을 변경해야합니다. (즉, new 사용)

+0

답해 주셔서 감사합니다. 나는 프로젝트에 대한 지침과 함께 PDF 파일을 가지고 있고 그것들은 내 std :: list에 std :: pair 객체의 포인터를 포함해야한다고 말하고있다. –

+0

그런 경우 스택 대신 힙에 객체를 만들려면 객체를 새로 작성해야합니다.pre-C++ 11의 경우 가이드 라인이 더 효율적이지만 단점은 모든 메모리를 직접 관리해야한다는 것입니다. 문제는 스택에 객체를 만드는 것인데, 함수를 빠져 나갈 때 사라진다. Lateron은 인쇄 중에 더 이상 존재하지 않는 개체에 액세스하려고 시도합니다. – tillaert