【发布时间】:2017-11-18 05:21:45
【问题描述】:
我有一个 2 级哈希表,如 here(uthash) 所述,具有如下声明的两个不同结构。哈希结构 b 通过哈希结构 a 中的参数 d 保存 s 值的总数及其频率(为了更好地理解,请看下面的设计)。
update 函数应该是这样工作的:如果第一次遇到 s,则将其添加到 struct myb 并添加到 struct mya。如果它已经在 struct myb 中,则检查是否第一次遇到它的 d 值,以防将其添加到 struct mya 中,否则将其值递增。
但是,当我运行代码时,它会将第一次遇到的 d 值保存在哈希结构 mya 中(并在这种情况下增加),但我没有添加在相同 s 值上收到的其他 d 值...代码有什么问题?
d1:3 d2:5
/ /
s1 - d2:4 s2 - d4:3
\ \
d3:1 d5:2
---------------------------
#include <stdio.h>
#include <string.h>
#include "uthash.h"
struct a{
int x;
int count;
UT_hash_handle hh;
};
struct b{
char s[24];
int total;
struct a *mya;
UT_hash_handle hh;
};
void update(struct b **myb, const char *s, u_int32_t d){
struct b *pb;
HASH_FIND_STR(*myb, s, pb);
if(pb == NULL) {
pb = (struct b*)malloc(sizeof(struct b));
if(!pb) return;
strncpy(pb->s, s, sizeof(pb->s));
pb->total = 1;
pb->mya = NULL;
HASH_ADD_STR(*myb, s, pb);
struct a *pa = (struct a*)malloc(sizeof(struct a));
if(!pa) return;
pa->x = d;
pa->count = 1;
HASH_ADD_INT(pb->mya, x, pa);
}
else{
struct a *pp=NULL;
pb->total++;
HASH_FIND_INT(pb->mya, &d, pp);
if(pp == NULL){
pp = (struct a*)malloc(sizeof(struct a));
if(!pp) return;
pp->count = 1;
HASH_ADD_INT(pb->mya, x, pp);
}
else pp->count++;
}
}
void printAll(struct b *myb){
struct b *pb, *tmp;
struct a *pa, *tmp2;
int i = 0, j = 0;
HASH_ITER(hh, myb, pb, tmp) {
i++;
printf("%d) %s: %u\n", i, pb->s, pb->total);
HASH_ITER(hh, pb->mya, pa, tmp2) {
j++;
printf("\t%d) %u: %u\n", j, pa->x, pa->count);
}
j = 0;
}
}
struct b *myb = NULL;
int main(int argc, char **argv ){
char str[10][24] = {"abc","abc","def","abc","hij","def","hij","def","abc","hij"};
int values[10] = {10, 10, 9, 8, 5, 2, 6, 2, 5, 5};
int i;
for(i=0; i<10; i++)
update(&myb,str[i],values[i]);
printf("hash table\n");
printAll(myb);
return 0;
}
【问题讨论】:
-
什么是变量
my,出现在HASH_ADD_STR(*my, s, pb)?这看起来不像你想要的,假设整个代码都可以编译。 -
@PaulOgilvie,不,它确实有效,它确实将新的 s 值添加到哈希表中。问题在于 d 值。 pb 是结构体,如果找到它则返回搜索值,如果找不到则返回 null。
-
@JohnBollinger,这只是一个类型错误。我修好了它。它必须是 myb 结构。
-
另外,什么是变量
f?您的原始代码可能有效,但您在此处向我们展示的内容似乎不起作用。 -
看来
HASH_FIND_STR(*myb, s, pb)是一个宏,它取了输出参数pb的地址。所以那里似乎没有错。使用调试器单步调试代码?