2011-12-02 71 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) 
{}