它显示了我的主函数在HTSize时对大小8的无效读取,对于空散列,它似乎可以工作(它打印0),但我认为问题是,HTCreate中的初始化散列作为HTSize中的参数传递,但已单元化。
我试过(不在显示的代码中)将参数作为定义为HTSize(HThash**)的&Table传递,但程序没有运行,valgrind也显示“地址0x0不是stack'd、malloc'd或(最近)free'd”。在函数内部,我还将一个指针T放在散列上,以取消对**散列的引用。我在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中,但我不确定。我检查了hash是否在主函数中初始化,它确实初始化了。
最佳答案
您的问题在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
对这个值没有影响。由于这是函数的本地操作,在另一个函数中使用它可能会导致任何事情(未定义的行为)
从函数返回所需内容的好方法是返回
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));
}