首页 > 解决方案 > 在 .. 处读取的大小为 8 的无效读取

问题描述

它显示我的主函数在 HTSize 处对大小 8 的无效读取,并且对于空哈希似乎有效(它打印 0)但我认为问题是我的 HTCreate 中的初始化哈希作为 HTSize 中的参数传递但是统一化。

我尝试过(不在显示的代码中)将参数作为 &Table 传递,定义为 HTSize(HThash**) 但没有解决它,程序没有运行并且 valgrind 显示“地址 0x0 未堆叠, malloc'd 或(最近)free'd”。在函数内部,我还放置了一个指向哈希的指针 T 以取消引用 **hash。我在 linux 中工作。

typedef char* KeyType;
typedef int HTItem;
typedef struct node{
    KeyType key;
    HTItem item;
    struct node *next;
}List;
typedef struct {
    List *head;
}TableEntry;
typedef TableEntry *HTHash;

HTHash* HTCreate(void);
int HTSize(HTHash);

int TABLESIZE = 10;

int main(void)
{
    HTItem *p;
    HTHash *Table = HTCreate();
    printf("%d\n",HTSize(*Table));
}

HTHash* HTCreate(void)
{
    int i;
    HTHash table = (HTHash)malloc(TABLESIZE*sizeof(TableEntry));
    HTHash *T;
    for(i=0;i<TABLESIZE;i++)
        table[i].head = NULL;
    T = &table;
    return T;
}

int HTSize(HTHash hash)
{
    int i,count=0;
    List *temp = (List*)malloc(sizeof(List));   
    for(i=0;i<TABLESIZE;i++)
    {
        if(hash[i].head != NULL)
        {
            count++;
            temp = hash[i].head->next;
            while(temp != NULL)
            {
                count++;
                temp = temp->next;
            }
        }   
    }
    return count;   
}

错误可能出在 HTCreate 但我不确定。我检查了哈希是否在主函数中初始化并且确实如此。

标签: chashsegmentation-fault

解决方案


您的问题实际上出在HTCreate函数中:它返回&table函数的本地。

演示:

HTHash *HTCreate(void)
{
    int i;

    HTHash table = NULL;

    printf("&table before malloc: %p\n", &table);

    table = malloc(TABLESIZE*sizeof(TableEntry));

    printf("&table after  malloc: %p\n", &table);

    HTHash *T;

    for(i=0;i<TABLESIZE;i++)
        table[i].head = NULL;

    T = &table;
    return T;
}

将打印:

&table before malloc: 0x7fff200eb818
&table after  malloc: 0x7fff200eb818

我们看到这malloc对这个值没有影响。

由于 this 是函数的本地函数,因此在另一个函数中使用 this 可能会导致任何事情(未定义的行为)

从函数返回所需内容的好方法是返回一个HTHash类型:

HTHash HTCreate(void)
{
    int i;

    HTHash table = malloc(TABLESIZE*sizeof(TableEntry));

    for(i=0;i<TABLESIZE;i++)
        table[i].head = NULL;

    return table;
}

看看里面做了什么,我发现这个功能可以简化:

HTHash HTCreate(void)
{
    return calloc(TABLESIZE, sizeof(TableEntry));
}

推荐阅读