尽管堆分配,一旦函数退出,内存超出范围?

时间:2014-04-05 04:54:20

标签: c scope allocation heap-memory

一般问题:实施字典。

具体问题:根据gdb,我的分配和一切都正常工作。一旦使用" c"的键调用types_dict_add,就会出现问题。一切都按原样再次分配,整个字典在整个函数上下文中都是完整的(所有指针都是可访问的,这些指针的结构都有它们的设置值),但是一旦函数退出到main,{{1}指针都超出范围。存储在mydict中的实际指针地址都未更改,但突然无法访问。在使用" c"进行呼叫之前,mydict也完好无损,因为它应该在main.c中。

我在这里做错了什么?这让我很困惑,因为我一遍又一遍地检查了gdb并正确设置了mydict值,因此肯定有足够的空间len&# 39; d各自去。

types.h中

realloc

types.c

#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

的main.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;
    }
}

2 个答案:

答案 0 :(得分:2)

types_dict_add中修改本地变量d。此更改未反映在main的变量mydict中,因为C按值传递函数参数。如果您希望types_dict_add能够在realloc上执行mydict,则需要添加额外的间接级别。

我认为使用长度计数而不是终止NULL会更简单;那么你可以使你的控制结构像:

struct dict
{
    struct kv **members;
    size_t n_members;
};

这也可以避免三重指针(有些人对此感到不舒服)。

答案 1 :(得分:1)

始终检查realloc的返回值。 realloc在某些情况下可能会失败。

d = realloc(d, sizeof(struct kv*) * 2);

在访问d之前进行检查。