【发布时间】:2017-04-22 14:01:32
【问题描述】:
我有一个结构如下的文件:
finance
www.lemonde.fr 4
|
Brexit:
www.lemonde.fr 2
|
divorce
www.lemonde.fr 2
www.lequipe.fr 8
|
amiable
www.lemonde.fr 2
|
rupture
www.lemonde.fr 2
www.leparisien.com 3
www.lequipe.fr 2
|
Economie
www.lemonde.fr 1
|
Entreprises
www.lemonde.fr 2
www.laposte.fr/particulier 1
|
xiti
www.laposte.fr/particulier 1
|
文件实际上要大得多,这是最后几行。
我的目标是将此文件加载到哈希表中。 关键是每个块的第一个单词。 该值将是指向此结构的指针:
typedef struct wordInfo {
char **urls_list;
int *nbOccurence;
int size;
} wordInfo;
主要功能:
int main(){
GHashTable *hash = loadIndex("index.txt");
printf("Nombre de clé dans la table: %d\n", g_hash_table_size(hash));
g_hash_table_foreach(hash, (GHFunc)iterator, "Cle: %s, Value: %p\n");
wordInfo* x = g_hash_table_lookup(hash, "xiti");
if(x == NULL){
printf("NULL\n");
}
printf("Taille: %d",x->size);
for(int i = 0 ; i < x->size ; i++){
printf("Lien: %s\n", (x->urls_list)[i]);
}
g_hash_table_destroy(hash);
return 0;
}
加载文件的函数,loadIndex():
GHashTable* loadIndex(char *filename){
FILE *f=fopen(filename,"r");
GHashTable* hash = g_hash_table_new(g_str_hash, g_str_equal);
char *word=malloc(100);
while(fgets(word,100,f)!=NULL) { // reading a word
char *aux=strchr(word,'\n'); // removes the trailing \n
aux[0]='\0';
// we make a structure for the wod we just found
wordInfo *x = g_malloc(sizeof(wordInfo));
x->urls_list = malloc(sizeof(char)*100);
x->size = 0;
x->nbOccurence = malloc(sizeof(int)*100);
char *line = malloc(100);
while(fgets(line,100,f)!=NULL){ //read urls for the found word
if(!strcmp(line,"|\n")){ // until we find character |
break;
}
char *url = strtok(line," ");
char *occ = strtok(NULL," ");
x->urls_list[x->size] = malloc(strlen(url));
strcat(x->urls_list[x->size],url);
x->nbOccurence[x->size] = atoi(occ);
x->size += 1;
}
char* key;
key = g_strdup(word);
g_hash_table_insert(hash, key ,(wordInfo*)x);
}
return hash;
}
foreach 的输出是:
Cle: xiti, Value: 0x978b40
Cle: xiti, Value: 0x687e60
Cle: xiti, Value: 0xb23830
Cle: xiti, Value: 0x86b1f0
Cle: xiti, Value: 0x81e890
Cle: xiti, Value: 0x9df7c0
Cle: xiti, Value: 0x6b0330
Cle: xiti, Value: 0x9eef10
如您所见,我没有不同的单词作为键,而只有文件中的最后一个键。另外我不明白我如何可以拥有多次相同的键,不是假设包含唯一钥匙?
【问题讨论】:
-
只是基于快速浏览,像
wordInfo *x = g_malloc(sizeof(wordInfo*));这样的行是一个问题。您要求 malloc 为指向 wordInfo 的指针(可能是 4 或 8 个字节)分配足够的空间,而不是整个 wordInfo (可能是 12 或 20 个字节)。应该是wordInfo *x = g_malloc(sizeof(wordInfo));。您可能还想考虑使用g_new(并启动编译器警告),它将结果转换为正确的类型,以便编译器可以捕获如下错误:wordInfo *x = g_new(wordInfo, 1); -
感谢您的回答!我编辑了代码,但正如预期的那样,它并没有改变问题。我觉得我应该如何使用哈希表有问题,但我想不通。
-
仍有两个损坏的 malloc 调用…
malloc(sizeof(char*)*100)返回char**而不是char*,malloc(sizeof(int*)*100)返回int**而不是int*。完成后,您应该专注于从测试用例中消除代码。解析是否按预期工作?如果是这样,请将其替换为结构数组或其他内容。继续消除你能消除的任何东西,直到消除一些东西解决了问题,然后至少你会知道哪里问题出在哪里。 -
我错过了那些,谢谢。我编辑了代码。在插入哈希表之前,我打印了添加的单词,这似乎是我所期望的。但是当我在主要的时候,所有的键都是最后一个词。
-
您应该使用
valgrind的memcheck工具来诊断类似这样的内存管理问题。