2011-12-02 50 views
0
#define TABLE_SIZE 100489 // must be a power of 2 
typedef map<string,int> MAP_TYPE; 
typedef pair<string, int> PAIR_TYPE; 

class HashTable 
{ 
public:          //public functions 
    HashTable(); 
    ~HashTable(); 
    int find(string); 
    bool insert(string, int); 
private: 
    int hash(const char*); 
    vector<MAP_TYPE> v; 
}; 

//HashTable constructor 
HashTable::HashTable() 
{ 
    vector<MAP_TYPE> v;    //initialize vector of maps 
    v.reserve(TABLE_SIZE);     //reserve table size 
    MAP_TYPE m; 
    for (int i = 0; i < TABLE_SIZE; ++i) //fill vector with empty maps 
    v.push_back(m); 
    cout << v.size(); 
} 

int HashTable::find(string key) 
{ 
    cout << "in find" << '\n'; 
    //String to const char* for hash function 
    const char *c = key.c_str(); 
    //find bucket where key is located 
    int hashValue = HashTable::hash(c); 
    cout << hashValue << '\n'; 
    string s = key; 
    cout << v.size(); //Prints 0 but should be TABLE_SIZE 
    //look for key in map in bucket 
    MAP_TYPE::const_iterator iter = v[hashValue].find(s); 
    if (iter != v[hashValue].end()) //check if find exists 
     return iter->second; //return value of key 
    else 
     return -1; //arbitrary value signifying failure to find key 
} 

int main() 
{ 
    HashTable my_hash; 
    string s = "hi"; 
    int z = my_hash.find(s); 
    cout << z; //should return -1 
    return 0; 
} 

我測試了查找函數我的哈希表,但它返回一個分段錯誤。即使我在查找函數中構建了具有正確大小的向量v,大小現在爲0?我不認爲它正在訪問相同的變量。散列函數很好。怎麼了?分段錯誤訪問私有類變量

+8

100489 = 2的冪 – Mysticial

+2

@Mysticial,這就是爲什麼評論做出不好的斷言陳述。 –

+0

eeep!是的,但這應該不重要...哈希在矢量的大小範圍內。 v.size()在find中不應該給我0兩種方式? – Benjamin

回答

1

你永遠不會實際插入任何東西到私人成員變量載體v。你創建一個向量作爲本地堆棧變量,其中也是名稱v,在你的HashTable構造函數中。然後,您繼續將項目插入到臨時向量中,只要您離開構造函數就會超出範圍。所以當然,以後在HashTable::find函數中,類成員變量v是空的。

你的構造應該是這樣的:

//HashTable constructor 
HashTable::HashTable() 
{ 
    this->v.reserve(TABLE_SIZE);     //reserve table size 
    MAP_TYPE m; 
    for (int i = 0; i < TABLE_SIZE; ++i) //fill vector with empty maps 
     this->v.push_back(m); 
} 

上面我用this關鍵字強調的是,我在訪問私有成員變量v,但你並不需要它。 (雖然,通常它採用了私有成員變量,如添加_後綴或m_前綴或東西命名約定好的做法。)

一個更好的方法來初始化向量是簡單地使用矢量的填充構造函數,如R. Martinho Fernandes's答案中建議。

1

你有所謂的V以及私有類成員訴函數的局部變量

嘗試: this->v

2

在C++類變量在初始化列表最好的初始化:

HashTable::HashTable() : v(TABLE_SIZE, MAP_TYPE()) // **here** 
{} 

std::vector有一個構造函數,它需要一個大小和一個默認值,所以你可以調用它。事實上,自從使用默認值實際上是默認的構造函數創建一個地圖,你實際上可以像下面,因爲第二個參數可以在這種情況下可以省略:

HashTable::HashTable() : v(TABLE_SIZE) 
{}