Question

I'm setting up and loading a hashtable, using linked lists. For each item, I calloc a struct pointer, then enter that item into the array itself, or the associated linked list if the array index is taken.

All works beautifully, but valgrind is telling me I have a "definitely lost" at the line where I am calloc'ing the struct item.

Now, I'm new to C, but am familiar with Objective-C. In pre-ARC days, you could alloc an object, put it in an array, then release it. The array would retain the object. Once you needed to pull the item out of the array, you would need to retain it first. Otherwise, it would be lost quickly as the array would no longer be retaining the object.

So, I guess my question is: how do I get an array/linked list to retain its "objects", so I can free the alloc'd item after entering it into the array or linked list?

// global array
struct_item** hashtable;

// declare struct
typedef struct struct_item
{
    char item1[SIZE + 1];
    struct struct_item* next_item;
}

// later... dynamically allocate hashtable
hashtable = calloc(sizevar, sizeof(struct_item);

// later, inside of a loop...
// alloc struct item to go into array/linked list (valgrind error happening here)
struct_item* an_item = calloc(1, sizeof(struct_item);

// after setting appropriate values in 'an_item', add struct to hashtable
hashtable[0] = an_item;

// after all is said and done, free the current (remaining) struct_item
// (edit to fix: wasn't struct_item; should've been an_item)
//free(struct_item);
free(an_item);

I'm not freeing any of the other struct_items calloc'd during the loop; just the last one. But, as soon as I free that one, it's value disappears from the hashtable.

Ideally, I suppose I'd be freeing each one of the calloc'd struct_items, yes? Valgrind is only reporting one issue, located at the line where I'm calloc'ing 'an_item'.

So, again, how do I get the calloc'd items to stay associated with the hashtable, so I can free 'an_item' without it's data disappearing from the table? What am I missing???

Edit to add note: I do free the struct_items when I'm unloading the hashtable/linked list!

Was it helpful?

Solution

Found it!

I was freeing everything from the linked list during the unload - but not the actual item at the current hashtable index!

Once I freed hashtable[i] correctly, I got the happy report:

==6759== 
==6759== HEAP SUMMARY:
==6759==     in use at exit: 0 bytes in 0 blocks
==6759==   total heap usage: 143,130 allocs, 143,130 frees, 14,883,824 bytes allocated
==6759== 
==6759== All heap blocks were freed -- no leaks are possible
==6759== 
==6759== For counts of detected and suppressed errors, rerun with: -v
==6759== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

OTHER TIPS

This line is problematic

// after all is said and done, free the current (remaining) struct_item
free(struct_item);

Change to as 'an_item' contains address returned by the calloc

  free(an_item);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top