Reputation: 13
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
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
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