Jake
Jake

Reputation: 78

Passing a pointer to an array of structures

I am having issues with a book assignment that I have been working on, hoping to get some help. My program compiles without issue, but when I run it, I get

First time through: (null)
After: 0000000
First time through: (null)
After: 1111111

When I insert a hash it checks to see if that array value has already been assigned. If it does, it prints "Collision detected" and it creates a new node and links it to the previous node. Right now it seems like its an automatic variable even though I am passing it a pointer?

I am pretty sure it has to do with how I am declaring my array of structures and passing them into insert_hash, but I cant seem to figure it out. Any help is appreciated!

struct hash_node
{
    char *data;
    struct hash_node *next;

};

struct hash_node *create_table(int size);
unsigned int hash(const char *str);
void insert_hash(const char *str, const char *value, struct hash_node *h);

int
main(void)
{   
    struct hash_node *table = create_table(101);

    insert_hash("testing", "0000000", table);
    insert_hash("testing", "1111111", table);


}

struct hash_node
*create_table(int size)
{
    struct hash_node *table = calloc(size, sizeof(*table));

    if(!table)
    {
        fprintf(stderr, "Unable to allocate memory\n");
        return NULL;
    }

    return table;
}

unsigned int
hash(const char *str)
{
    unsigned int c, hash;

    while ((c = *str++))
    {
        hash += c;
    }

    hash = hash % 100;

    return hash;
}

void
insert_hash(const char *str, const char *value,  struct hash_node *h)
{
    int temp = hash(str);

    printf("First time through: %s\n", h[temp].data);

    if (h[temp].data)
    {
        fprintf(stderr, "Collision detected\n");

        struct hash_node *node = calloc(1, sizeof(*node));

        if (!node)
        {
            fprintf(stderr, "Unable to allocate memory\n");
            return;
        }

        node -> data = malloc(strlen(value) + 1);
        strncpy(node -> data, value, strlen(value) + 1);

        node->next = NULL;

        h[temp].next = node;
    }
    else
    {

        h[temp].data = malloc(strlen(value) + 1);
        strncpy(h[temp].data, value, strlen(value) + 1);
    }

    printf("After: %s\n", h[temp].data);

}

Upvotes: 0

Views: 76

Answers (1)

Pablo
Pablo

Reputation: 13590

The hash function is wrong

unsigned int
hash(const char *str)
{
    unsigned int c, hash;   //<--- not initialized

    while ((c = *str++))
    {
        hash += c;
    }

    hash = hash % 100;

    return hash;
}

The hash variable is not initialized, so it has an undefined value every time you execute it. Initialize it with 0:

unsigned int
hash(const char *str)
{
    unsigned int c, hash = 0;

    while ((c = *str++))
    {
        hash += c;
    }

    hash = hash % 100;

    return hash;
}

Then I get

First time through: (null)
After: 0000000
First time through: 0000000
Collision detected
After: 0000000

edit

In case of a collision you are also not appending the new node correctly. You first have to find the end of the list and then append the new node at the end of the list:

node *tail = h[temp].next;

while(tail->next)
    tail = tail->next;


struct hash_node *node = calloc(1, sizeof(*node));
...

tail->next = node;

Or you can preprend the new node at the beginning of the list

struct hash_node *node = calloc(1, sizeof(*node));
...

node->next = h[temp].next;
h[temp].next = node;

Upvotes: 1

Related Questions