1
votes

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.

1
Please provide minimal reproducible example including type definitions.Eugene Sh.
Hi, welcome to Stack Overflow. The defintiion of HTHash seems to be missing from your code. Please edit it into the question to provide a minimal reproducible example.Angew is no longer proud of SO
HTCreate is returning a pointer to a local variable table.Ian Abbott
What is the use of returning HTHash* from HTCreate, instead of plain HTHash?Some programmer dude

1 Answers

1
votes

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));
}