Reputation: 237
I have structs like this:
struct Child
{
int foo;
char bar[42];
};
struct Parent
{
long foobar;
struct Child ** children;
size_t num_children;
}
I have defined an API like this:
struct Parent * ParentAlloc() { struct Parent* ptr = (struct Parent*)calloc(1, sizeof(struct Parent));
ptr->children = (struct Child**)calloc(SOME_NUMBER, sizeof(struct Child*));
return ptr;
}
Now, if I want to delete a (previously allocated) child - assuming index is not out of bounds:
void FreeChild(struct Parent* parent, const size_t index)
{
free(parent->children[index]);
//now I want to mark the address pointed to in the array of pointers as null, to mark it as available
//I dont think I can do this (next line), since I have freed the pointer (its now "dangling")
parent->children[index] = 0; // this is not right. How do I set this 'freed' address to null ?
}
Upvotes: 0
Views: 542
Reputation: 4342
Of course you can do this. A pointer is a variable whose value is an address. It's perfectly okay, actually good practice, to set pointers to 0 (or NULL) after calling free, so that you can check them for being non-null and avoid segfaults. Bottom line: Your code is okay.
Upvotes: 2
Reputation: 84199
You are mixing array of pointers with array of structures. Remove double star and operate on offsets:
...
struct Parent
{
long foobar;
struct Child* kids;
size_t numkids;
};
...
struct Parent * ParentAlloc()
{
struct Parent* ptr = ( struct Parent* )calloc( 1, sizeof( struct Parent ));
ptr->kids = ( struct Child* )calloc( SOME_NUMBER, sizeof( struct Child ));
ptr->numkids = SOME_NUMBER; /* don't forget this! */
return ptr;
}
...
struct Child* GetChild( struct Parent* p, size_t index )
{
assert( p );
assert( index < p->numkids );
return p->kids + index;
}
Upvotes: 0
Reputation: 4112
There is no problem with setting the parent->children[index] to NULL. You only freed the memory where the pointer points to, not the memory where the pointer itself is stored.
Upvotes: 2