free functions design

M

Manish Tomar

Hi,

Assume I am developing a library that have couple of structs storing
some information:
struct A {
char *c;
struct B *b;
};
struct B {
char *str;
};

These structs are alloced on heap (I know I know.. C standard doesnt
define heap but I didnt know what else to write) using some lib API
and after using them the user frees it using their free functions
freeA() & freeB().

As a design decision I was wondering if the free functions should be
written like standard lib free function which does nothing when NULL
is passed or throw an error when NULL is passed. In other words,
should it expect NULL? If so, what should it do?

I am sorry if this seems like a real dumb question.

Thanks in advance,
Manish
 
C

Chris Dollin

Manish said:
Assume I am developing a library that have couple of structs storing
some information:
struct A {
char *c;
struct B *b;
};
struct B {
char *str;
};

These structs are alloced on heap (I know I know.. C standard doesnt
define heap but I didnt know what else to write) using some lib API
and after using them the user frees it using their free functions
freeA() & freeB().

I'm not sure that's a wise design. Your A objects point to B objects.
Do they own them or not? If an A object owns the B object it points
to, then freeA should -- IMAO -- call freeB on the B pointer. If
not, then it shouldn't -- but then blindly freeing the B object when
you free the A object is likely to be a mistake.

Does the user have to see the A and B structures separately (or
indeed at all)?
As a design decision I was wondering if the free functions should be
written like standard lib free function which does nothing when NULL
is passed or throw an error when NULL is passed. In other words,
should it expect NULL? If so, what should it do?

It should do whatever makes the code that uses it clear and
straightforward, and fit in with your local error-detection
and recovery policy.
 
C

CBFalconer

Manish said:
.... snip ...

These structs are alloced on heap (I know I know.. C standard doesnt
define heap but I didnt know what else to write) using some lib API
and after using them the user frees it using their free functions
freeA() & freeB().

Just write "These structures are malloced".
As a design decision I was wondering if the free functions should be
written like standard lib free function which does nothing when NULL
is passed or throw an error when NULL is passed. In other words,
should it expect NULL? If so, what should it do?

Just use the standard 'free' function. Why should it detect NULL?
 
M

Malcolm McLean

Manish Tomar said:
Hi,

Assume I am developing a library that have couple of structs storing
some information:
struct A {
char *c;
struct B *b;
};
struct B {
char *str;
};

These structs are alloced on heap (I know I know.. C standard doesnt
define heap but I didnt know what else to write) using some lib API
and after using them the user frees it using their free functions
freeA() & freeB().

As a design decision I was wondering if the free functions should be
written like standard lib free function which does nothing when NULL
is passed or throw an error when NULL is passed. In other words,
should it expect NULL? If so, what should it do?

I am sorry if this seems like a real dumb question.
Silently suppress calls with null parameters.

eg
void killA(struct A *a)
{
if(a)
{
free(a->c);
killB(a->b);
free(a);
}
}

void killB(struct B * b)
{
if(b)
{
free(b->str);
free(b);
}
}

from experience this removes masses of checks and free calls from your code
as you destroy partially-completed objects.
 
R

Roland Pibinger

As a design decision I was wondering if the free functions should be
written like standard lib free function which does nothing when NULL
is passed or throw an error when NULL is passed. In other words,
should it expect NULL? If so, what should it do?

IMO, 'do it like the standard does' is a good rule of thumb.
 
M

Manish Tomar

IMO, 'do it like the standard does' is a good rule of thumb.

Thanks a lot Roland & Malcolm. Thats what I had in mind earlier. Just
wanted to take opinions from others?
 
D

Duncan Muirhead

Thanks a lot Roland & Malcolm. Thats what I had in mind earlier. Just
wanted to take opinions from others?
For what it's worth, while I agree that quietly doing nothing with
NULL is the way to go, I like free-like functions to return NULL.
I find it marginally easier to write "p = free_it( p);" than
"free_it(p); p = NULL;"
Duncan
 
R

Richard Bos

Duncan Muirhead said:
For what it's worth, while I agree that quietly doing nothing with
NULL is the way to go, I like free-like functions to return NULL.
I find it marginally easier to write "p = free_it( p);" than
"free_it(p); p = NULL;"

But why would you do that anyway? If you rely on only freed pointers
being null, you are going to forget a copy you made sooner or later. It
is much more reliable to get into the habit of properly keeping track of
which pointers are live and which aren't, rather than depending on a
half-working trick.

Richard
 
M

Malcolm McLean

Richard Bos said:
But why would you do that anyway? If you rely on only freed pointers
being null, you are going to forget a copy you made sooner or later. It
is much more reliable to get into the habit of properly keeping track of
which pointers are live and which aren't, rather than depending on a
half-working trick.
Pointer aliasing is a huge problem. If you have more than one pointer to an
object, you should make sure that it is part of a well-defiend structure,
like a linked list, which can be destroyed in one go.

However that is easier said than done. BabyX, my new X toolkit, is a mass of
pointers and function pointers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top