一般问题:实现字典。
具体问题:根据 gdb,我的分配和一切都按预期工作。一旦使用“c”键调用 types_dict_add 就会出现问题。一切都再次按应有的方式分配,并且整个字典在整个函数上下文中都是完整的(所有指针都可以访问并且这些指针处的结构具有它们的设置值),但是一旦函数退出回到 main,mydict
指针都越界了。 mydict
中存储的实际指针地址都没有变化,但突然无法访问。在使用“c”调用之前,mydict
也是完整无缺的,因为它应该在 main.c 中
我在这里做错了什么?这真的让我感到困惑,因为我一遍又一遍地检查 gdb 并且 len
值设置正确,所以肯定有适当数量的空间被 realloc
每次去。
类型.h
#ifndef _TYPES_H_
#define _TYPES_H_
union types {
long int ival;
char *sval;
};
struct kv {
char* key;
union types val;
};
struct kv **types_dict_init();
void types_dict_add(struct kv**, char*, union types);
struct kv *types_dict_get(char*);
void types_dict_free(struct kv**);
#endif
类型.c
struct kv **
types_dict_init()
{
struct kv **newdict;
newdict = calloc(1, sizeof(struct kv*));
newdict[0] = NULL;
return (newdict);
}
void
types_dict_add(struct kv** d, char* k, union types v)
{
int len;
if (d[0] == NULL) {
d = realloc(d, sizeof(struct kv*) * 2);
d[0] = malloc(sizeof(struct kv));
d[0]->key = k;
d[0]->val = v;
d[1] = NULL;
} else {
for (len = 1; d[len - 1] != NULL; len++)
;
d = realloc(d, sizeof(struct kv*) * ++len);
d[len - 2] = malloc(sizeof(struct kv));
d[len - 2]->key = k;
d[len - 2]->val = v;
d[len - 1] = NULL;
}
}
主.c
#include <stdio.h>
#include <stdlib.h>
#include "bencode/types.h"
int main(int argc, char **argv)
{
struct kv **mydict;
union types toadd;
toadd.sval = "test";
mydict = types_dict_init();
types_dict_add(mydict, "a", toadd);
types_dict_add(mydict, "b", toadd);
types_dict_add(mydict, "c", toadd);
types_dict_add(mydict, "d", toadd);
for(int i = 0; i < 4; i++)
printf("%d: %s\n", i, mydict[i]->key);
return (EXIT_SUCCESS);
}
最佳答案
在 types_dict_add
中,您修改局部变量 d
。此更改未反射(reflect)在 main
的变量 mydict
中,因为 C 按值传递函数参数。如果您希望 types_dict_add
能够在 mydict
上执行 realloc
,则需要添加额外的间接级别。
我认为使用长度计数而不是终止 NULL 会更简单;然后你可以让你的控制结构是这样的:
struct dict
{
struct kv **members;
size_t n_members;
};
这也可以避免三重指针(有些人对此感到不舒服)。
关于c - 尽管分配了堆,但一旦函数退出,内存就会越界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22876742/