Kaitlin Bleich
Kaitlin Bleich

Reputation: 13

array of linked lists initialization

Before I get downvoted for not looking at "similar" questions, I couldn't find anyone who actually tried to initialize an entire malloced "array" to NULL.

I'm trying to create a hash table. The first malloc is for the array, the second malloc is for creating the hash table struct to put the array in. I plan to implement collision chaining with a linked list (called ListNode here). After mallocing space for the array and putting it in the struct, I'd like to initialize all linked lists inside the array to NULL.

As of right now, this code assigns the POINTERS to the linked lists to NULL (on accident...I don't know how to fix), so they point to memory position 0x0. And somehow, after 3 or so iterations through that for loop at the bottom, the entire hash table struct is now pointing to 0x0 and I get a seg fault.

How are my all of my pointers suddenly becoming null, and not just my linked lists? And how do I make it so that the ListNode pointer = NULL so I can perform normal linked list operations on them?

typedef struct
{
    ListNode **array;
    /* more stuff */
} HTable;

void *HTCreate(unsigned sizes[], int numSizes){
  arr = (ListNode*)malloc(sizeof(ListNode) * sizes[0]);

  if(arr == NULL)
  {
      exit(1);
  }

  ht = (HTable*)malloc(sizeof(HTable));
  ht->array = &arr;
  ht->sizes = size;
  /* more initializing */
  for(i = 0; i < ht->sizes[ht->sizeIndex]; i++)
  {
      ht->array[i] = NULL;
  }

return (void *)ht; }

I have some theories...it's might be a problem with the &arr and me confusing things with double pointers, but I've tried this with both double pointers and single pointers in the struct, so I am thoroughly lost.

Thanks in advance!

Upvotes: 0

Views: 454

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 148880

You have a dangling pointer in your code, unless all your variable are global ones which would be bad design.

HTable *ht = malloc(sizeof(HTable));
...
return (void *)ht;

This one is fine: you return a pointer to allocated memory (note don't cast malloc in C)

But this one is wrong:

(ListNode*) arr = malloc(sizeof(ListNode) * sizes[0]);
...
ht->array = &arr;  

arr is a local pointer to an allocated memory bloc. You can safely return the address of the bloc (arr), but not the address of a local pointer to it (&arr).

Unless you have a good reason to do so, you should remove one indirection level:

typedef struct
{
    ListNode *array;
    /* more stuff */
} HTable;

and then

ht->array = arr;               // fine the address of an allocated bloc

If you really need the two indirection level, you must use a dynamically allocate pointer:

(ListNode*) arr = malloc(sizeof(ListNode) * sizes[0]);
...
(ListNode **)parr = malloc(sizeof(ListNode **));
ht->array = parr;              // fine the address of an allocated pointer

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409166

With the code you show, the only valid index of ht->array is 0. Everything else will be out of bounds.

If you want an array of pointers, you need to allocate such an array:

// Allocate an array of pointers, each pointer being initialized to NULL
ht->array = calloc(sizes[0], sizeof(ListNode *));

Upvotes: 1

Related Questions