0
typedef struct kvNode
{
    int key;
    int value;
    struct kvNode* next;
} kvNode_t;

typedef struct
{
    int size;
    kvNode_t** arrayOfKvNodes;
} hashTable_t;

bool hashTable_create(hashTable_t *ht, int size)
{
    int i;

    ht = (hashTable_t *)malloc(sizeof(hashTable_t));
    if(ht == NULL)
    {
        return false;
    }

    ht->size = size;

    ht->arrayOfKvNodes = (kvNode_t **)malloc(size * sizeof(kvNode_t *));
    if(ht->arrayOfKvNodes == NULL)
    {
        return false;
    }

    // initialize every cell to NULL
    for(i=0; i<size; i++)
    {
        ht->arrayOfKvNodes[i] = NULL;
    }

    return true;
}

void main()
{
    hashTable_t hashTableA;
            
    printf("Create Hash Table\n");
    hashTable_create(&hashTableA, 10);
    printf("Size of hash table: %d\n", hashTableA.size);
}

I'm trying to implement a hash table in C. I have a create function here that initializes an array of key-value nodes list **arrayOfKvNodes.

The above code results in an unexpected behavior. Create Hash Table
Size = -2039534832

However, when I try this function prototype: hashTable_t *hashTable_create(int size) and return a pointer to the malloced hashTable_t *, the code works fine.

What's the difference between these two?

pr123
  • 19
  • 3
  • This will _not_ compile. The compiler error is: `hash.c:48:47: error: invalid type argument of ‘->’ (have ‘hashTable_t’ {aka ‘struct ’})` In `main`, you define: `hashTable_t hashTableA;`. But, you try to use it as a _pointer_ with: `printf("Size of hash table: %d\n", hashTableA->size);`. You need: `printf("Size of hash table: %d\n", hashTableA.size);` Note the use of `.` instead of `->`. – Craig Estey Jan 05 '21 at 05:16
  • Although less desirable, you could do: `printf("Size of hash table: %d\n", (&hashTableA)->size);` but `hashTableA.size` is better. – Craig Estey Jan 05 '21 at 05:21
  • You could do: `hashTable_t hashTableA; hashTable_t *hashptr = &hashTableA;` and then do: `hashTable_create(hashptr,10);` and then: `printf("Size of hash table: %d\n", hashptr->size);` – Craig Estey Jan 05 '21 at 05:24
  • can you post error message? hashTableA->size should return a compilation error as hashTableA is not defined as a pointer, as explained by @CraigEstey. I ran your code in my system and it ran without any error. – Ankush Pandit Jan 05 '21 at 05:28
  • Aside from the other errors I mentioned, you have `hashTable_t *ht` as the _argument_ to `hashTable_create`. Upon entry, this points to caller's struct (i.e. the struct instance in `main`). But, you _trash_ that value with `ht = (hashTable_t *)malloc(size * sizeof(hashTable_t));`. Thus, all further operations operate on a _different_ copy [which produces a memory leak upon return]. Remove the `malloc` [et. al.] call. – Craig Estey Jan 05 '21 at 05:35
  • And, as you have it, you have a _single_ hash struct instance. So, even for your _original_ [not shown] function [that _returned_ a `hashTable_t *` pointer, you do _not_ want to do `malloc(size * sizeof(hashTable_t));` but merely `malloc(sizeof(hashTable_t));` You _only_ want to apply `size` to `arrayOfKvNodes` – Craig Estey Jan 05 '21 at 05:42
  • There is no _call by reference_ here, it is _call by value_ – IrAM Jan 05 '21 at 05:42
  • Thanks everyone! Edited the description to include dot operator during printing (hashTableA.size). However, the size returns an unexpected value as opposed to 10. – pr123 Jan 05 '21 at 06:16
  • Thanks to @CraigEstey! `ht = (hashTable_t *)malloc(size * sizeof(hashTable_t));` was a mistake. I corrected it now. I realize that I'm ending up reallocting memory on heap when the memory is already allocated on stack. Thanks for pointing it out :) – pr123 Jan 05 '21 at 07:01

0 Answers0