【发布时间】:2012-10-01 18:21:54
【问题描述】:
我有一个关于在 C++ 中向 std::map 插入内容的问题。
到目前为止,这就是我的代码:
stringutils.hh:
...
unsigned long hashSDBM(char *strToHash){
unsigned char* str = new unsigned char[strlen(strToHash) + 1];
strncpy( (char *) str, strToHash, strlen(strToHash) );
unsigned long hash = 0;
int c;
while ((c = *str++)){
hash = c + (hash <<6) + (hash <<16) - hash;
}
return hash;
}
...
hashmap.hh
#include "stringutils.hh"
namespace{
using namespace std;
class MapElement{
private:
char* filename;
char* path;
public:
MapElement(char* f, char* p):filename(f), path(p){}
~MapElement(){
delete [] filename;
delete [] path;
}
char* getFileName(){ return filename; }
char* getPath(){ return path; }
};
class HashMap{
private:
map<long*, MapElement*> *hm;
long hash(char* key);
public:
HashMap(){
hm = new map<long*, MapElement*>();
}
~HashMap(){
delete hm;
}
long put(char* k, MapElement *v);
};
long HashMap::hash(char* key){
return stringutils::hashSDBM(key);
}
long HashMap::put(char* k, MapElement *v){
long *key = new long();
*key = hash(k);
pair<map<long*,MapElement*>::iterator, bool> ret;
ret = hm->insert(std::pair<long*, MapElement*>(key, v));
if(ret.second == false){
cerr<<"Already exists: "<<ret.first->second->getFileName()<<endl;
return *key;
}
cerr<<"INSERTED "<<*key<<endl;
return 0;
}
main.cc:
HashMap *hm = new HashMap();
int main(void){
MapElement *m1;
char a[] = "hello";
char b[] = "world";
m1 = new MapElement(a,b);
hm->put(a, m1);
char c[] = "thats";
char d[] = "a test";
m1 = new MapElement(c,d);
hm->put(c, m1);
char e[] = "hello";
char f[] = "test";
m1 = new MapElement(e,f);
hm->put(e, m1);
return 0;
}
它编译时没有任何错误或警告,当我启动它时,会生成以下输出:
插入 7416051667693574450
插入 8269306963433084652
插入 7416051667693574450
为什么第二次插入“hello”键没有任何效果?
【问题讨论】:
-
你应该解释你的代码是做什么的,而不是仅仅粘贴它。
-
您的代码(函数
hashSDBM)内存泄漏。您应该使用std::string而不是原始的char *字符串。 -
这段代码存在严重的资源管理问题。
HashMap析构函数不会释放为所有键和值分配的内存。MapElement析构函数永远不会被调用,但如果调用它,它会出现段错误,因为它会在指向自动变量的指针上盲目调用delete[],而不是动态分配内存。两个类都不能正确处理复制或分配。请停止使用pointers和new。
标签: c++ hash insert duplicates stdmap