使用通过 POSIX hcreate
/hsearch
函数实现的关联数组(如 here 所述,我遇到了一些意想不到的行为,发现了我从未输入过的键,或者相反.
我追踪到一些按引用存储而不是按值存储的实例。
这让我感到惊讶,因为在示例中使用字符串文字作为键:
store("red", 0xff0000);
store("orange", 0x123456); /* Insert wrong value! */
store("green", 0x008000);
store("blue", 0x0000ff);
store("white", 0xffffff);
store("black", 0x000000);
store("orange", 0xffa500); /* Replace with correct value. */
这是一个显示我的问题的 MWE:
#include <inttypes.h> /* intptr_t */
#include <search.h> /* hcreate(), hsearch() */
#include <stdio.h> /* perror() */
#include <stdlib.h> /* exit() */
#include <string.h> /* strcpy() */
void exit_with_error(const char* error_message){
perror(error_message);
exit(EXIT_FAILURE);
}
int fetch(const char* key, intptr_t* value){
ENTRY e,*p;
e.key=(char*)key;
p=hsearch(e, FIND);
if(!p) return 0;
*value=(intptr_t)p->data;
return 1;
}
void store(const char *key, intptr_t value){
ENTRY e,*p;
e.key=(char*)key;
p = hsearch(e, ENTER);
if(!p) exit_with_error("hash full");
p->data = (void *)value;
}
void main(){
char a[4]="foo";
char b[4]="bar";
char c[4]="";
intptr_t x=NULL;
if(!hcreate(50)) exit_with_error("no hash");
store(a,1); /* a --> 1 */
strcpy(c,a); /* remember a */
strcpy(a,b); /* set a to b */
store(a,-1); /* b --> -1 */
strcpy(a,c); /* reset a */
if(fetch(a,&x)&&x==1) puts("a is here.");
if(!fetch(b,&x)) puts("b is not.");
strcpy(a,b); printf("But if we adjust a to match b");
if(fetch(a,&x)&&x==-1&&fetch(b,&x)&&x==-1) puts(", we find both.");
exit(EXIT_SUCCESS);
}
编译并执行上面的 C
代码会产生以下输出:
a is here.
b is not.
But if we adjust a to match b, we find both.
我将需要读取一个文件并存储大量的字符串:整数对,然后我将需要读取第二个文件来检查更大数量的字符串以获取先前存储的值。
如果通过引用比较键,我不明白这怎么可能。
如何更改我的关联数组实现以按值存储键?
如果这不可能,我该如何解决上述用例中的问题?
编辑:
这个问题只涉及输入但未找到的键。 相反的问题也出现了,在 this question 中有详细描述。
最佳答案
编辑:
事实证明,store()
需要strdup()
key
来解决这个问题和another problem .
我发现通过使用相同的变量进行存储和查找,我实际上可以检索数组中的所有值:
void main(){
char a[4]="foo";
char b[4]="bar";
char c[4]="baz";
char t[4]="";
intptr_t x=NULL;
if(!hcreate(50)) exit_with_error("no hash");
strcpy(t,a); store(t, 1); /* a --> 1 */
strcpy(t,b); store(t,-1); /* b --> -1 */
strcpy(t,c); store(t, 0); /* c --> 0 */
if(!fetch(a,&x)) puts("a is not here.");
if(!fetch(b,&x)) puts("Neither is b.");
if( fetch(c,&x)) puts("c is in (and equal to t).");
strcpy(t,a); if(fetch(t,&x)&&x== 1) puts("t can retrieve a.");
strcpy(t,b); if(fetch(t,&x)&&x==-1) puts("It also finds b.");
strcpy(t,c); if(fetch(t,&x)&&x== 0) puts("And as expected c.");
exit(EXIT_SUCCESS);
}
这会产生以下输出:
a is not here.
Neither is b.
c is in (and equal to t).
t can retrieve a.
It also finds b.
And as expected c.
但是,我还是不明白为什么会这样。
不知何故, key 似乎需要位于相同的位置(引用)并且包含相同的内容(值)才能被找到。
关于c - 如何在通过 hcreate/hsearch 按值(而不是按引用)实现的 C 中存储关联数组的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34749026/