void destroyFoo(Foo** foo)
{
if (!(*foo)) return;
Foo *tmpFoo = *foo;
*foo = NULL;
memset(tmpFoo, 0, sizeof(Foo));
free(tmpFoo);
}
Your colleague code is bad because
- it will crash if
foo
is NULL
- there's no point in creating additional variable
- there's no point in setting the values to zeros
- freeing a struct directly doesn't work if it contain things that has to be freed
I think what your colleague might have in mind is this use-case
Foo* a = NULL;
Foo* b = createFoo();
destroyFoo(NULL);
destroyFoo(&a);
destroyFoo(&b);
In that case, it should be like this. try here
void destroyFoo(Foo** foo)
{
if (!foo || !(*foo)) return;
free(*foo);
*foo = NULL;
}
First we need to take a look at Foo
, let's assume that it looks like this
struct Foo
{
// variables
int number;
char character;
// array of float
int arrSize;
float* arr;
// pointer to another instance
Foo* myTwin;
};
Now to define how it should be destroyed, let's first define how it should be created
Foo* createFoo (int arrSize, Foo* twin)
{
Foo* t = (Foo*) malloc(sizeof(Foo));
// initialize with default values
t->number = 1;
t->character = '1';
// initialize the array
t->arrSize = (arrSize>0?arrSize:10);
t->arr = (float*) malloc(sizeof(float) * t->arrSize);
// a Foo is a twin with only one other Foo
t->myTwin = twin;
if(twin) twin->myTwin = t;
return t;
}
Now we can write a destroy function oppose to the create function
Foo* destroyFoo (Foo* foo)
{
if (foo)
{
// we allocated the array, so we have to free it
free(t->arr);
// to avoid broken pointer, we need to nullify the twin pointer
if(t->myTwin) t->myTwin->myTwin = NULL;
}
free(foo);
return NULL;
}
Test try here
int main ()
{
Foo* a = createFoo (2, NULL);
Foo* b = createFoo (4, a);
a = destroyFoo(a);
b = destroyFoo(b);
printf("success");
return 0;
}