Reputation: 13
it shows invalid read of size 8 at HTSize by my main function and it seems to work(it prints 0) for an empty hash but what I believe is the issue is that the initialized hash in my HTCreate is passed as an argument in HTSize but unitialized.
I've tried(not in the code that is shown) passing the argument as &Table with the definition HTSize(HThash**) but instead of solving it the programm doesn't run and valgrind shows "Address 0x0 is not stack'd, malloc'd or (recently) free'd" as well. Inside the function I also put a pointer T to the hash to dereference the **hash.I work in 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;
}
The mistake may be in HTCreate but Im'not sure.I checked if the hash gets initialized in the main function and it does.
Upvotes: 1
Views: 113
Reputation: 9629
Your problem is effectivelly in HTCreate
function: it returns &table
which is local to the function.
Demo:
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;
}
Will print:
&table before malloc: 0x7fff200eb818
&table after malloc: 0x7fff200eb818
We see that malloc
is without effect on this value.
Since this is local to the function, using this in another function can cause anything (undefined behavior)
The good way to return what you need from the function is to return a HTHash
type:
HTHash HTCreate(void)
{
int i;
HTHash table = malloc(TABLESIZE*sizeof(TableEntry));
for(i=0;i<TABLESIZE;i++)
table[i].head = NULL;
return table;
}
Looking what is done in it, I saw that this function can be simplified :
HTHash HTCreate(void)
{
return calloc(TABLESIZE, sizeof(TableEntry));
}
Upvotes: 1