free()

C

Chris Dollin

Richard said:
[some re-flow]
Chris Dollin said:
Richard said:
Chris Dollin said:
Beej wrote:
void delete_goat(GOAT *g) { free(g); g = NULL; }

[...] where the assignment of NULL is completely pointless.

...but then it's a pointless function anyway.

It frees the store its argument points to and names what's
going on, so the /function/ isn't pointless.

free(whatever_you_would_have_passed_to_delete_goat); would do the same
trick, though - it frees the memory and (if the pointer is well-named)
documents what's going on as well, to anyone who knows what free() is
for - and if they don't know, why are we letting them touch production
code?

When goats are given additional pointer members (such as arms),
freeing a goat will have to deal with this. I find it easiest
to have a goatFree function right from the start, so that
I don't have to go free(aGoat)-hunting and change it. Calling
`free` directly risks forgetting to handle the insides ...

(destructor snipped)
It might not only be goats that use trollguns, and anyway there may be
other circumstances where you need to destroy a trollgun other than the
one where you are destroying - sorry! deleting - a goat.

Yes - but the same argument applies: either I'm going to destroy
the place that pointed to the gun, so no point nulling it, or I'm
going to give it a new value, so no point nulling it. That's the way
my code seemed to turn out, anyway.

[I write very little C these days: s'mostly Java. It's amusing
how each language highlights issues with the other ...]
[...] Probably because
we're writing different kinds of code. With a shared goal:
"don't let invalid pointers screw you up - get rid of them PDQ".

Yeah. The thing is, different people think in different ways.

So true. Not all different ways are bonkers.
 
R

raxitsheth2000

(e-mail address removed) said:




It's because malloc returns void * that you _don't_ need to cast it!





Writing programs whose output is undefined is not a good way to find
stuff out.


I find it helpful to ensure that any object pointer *either* points to a
valid object *or* has a value of NULL. If I do this, then I can be
assured that if(p != NULL) { p points to a valid object } but the price
of this assurance is that I must set p to NULL if it no longer points
to a valid object.

<snip>





You're wrong. Breaking the rules teaches you nothing about the language,
because by breaking the rules you are giving the implementation the
freedom to provide any behaviour whatsoever, or even no behaviour
whatsoever if it prefers.
i agree on most of your suggestion

may you have example that show the things and Don't Break rule for
what may be the behaviour of accessing memory after freeing even if
one SHOULD NOT access it. ?


Yes, programmers do have to be very very very careful. Because deadlines
are often unrealistic, mistakes happen. With experience, you will learn
how to identify these mistakes quickly.

what may be wrong if one is knowing the sizeof allocated memory and
memset with 0, and free it (and may be assign NULL to var) ? (except
performance--i agree.)

ISO/IEC 9899.

thanks for this,

--Raxit
 
R

Richard Heathfield

Chris Dollin said:

When goats are given additional pointer members (such as arms),
freeing a goat will have to deal with this. I find it easiest
to have a goatFree function right from the start, so that
I don't have to go free(aGoat)-hunting and change it.

Yes, likewise, which is why I write the destructor in the way I showed
you.
Yes - but the same argument applies: either I'm going to destroy
the place that pointed to the gun, so no point nulling it, or I'm
going to give it a new value, so no point nulling it.

No, there's another possibility - that the entity that had the gun no
longer has a gun (I dunno, perhaps the troll rips out the arm that was
holding it or something), and thus NULL is an appropriate value for
that pointer. For me, this is often the case, (not that I use trollguns
very often) - objects gain and lose other objects with careful abandon.

<snip>
 
C

Chris Dollin

Richard said:
Chris Dollin said:



Yes, likewise, which is why I write the destructor in the way I showed
you.


No, there's another possibility - that the entity that had the gun no
longer has a gun (I dunno, perhaps the troll rips out the arm that was
holding it or something), and thus NULL is an appropriate value for
that pointer.

Yes - sometimes the new value is null.

Sometimes, rather than nulling the pointer because you're freeing it
(well, the pointed-to object), you're freeing the pointer (ditto)
because you're nulling it [1].
For me, this is often the case, (not that I use trollguns
very often) - objects gain and lose other objects with careful abandon.

Indeed.

[1] And you know this is the only surviving usable reference.
 
R

Richard Heathfield

(e-mail address removed) said:

may you have example that show the things and Don't Break rule for
what may be the behaviour of accessing memory after freeing even if
one SHOULD NOT access it. ?

I am not sure that I understand your question. Once you've freed memory,
you are no longer allowed to use it. If you *do*, the C language
doesn't say what the result will be - so it could be anything. Maybe
nothing bad will happen. Maybe your computer will crash. Maybe
California will slide into the sea. And if it *does* slide into the
sea, it won't be San Andreas's fault.

what may be wrong if one is knowing the sizeof allocated memory and
memset with 0, and free it (and may be assign NULL to var) ? (except
performance--i agree.)

Again, I'm not sure what you mean. Once you've freed the memory, you
don't own it any more, so keep your hands off it.
 
C

Christopher Layne

Richard said:
Yeah. The thing is, different people think in different ways. There's
more than one way to do it, as the Perl people are so fond of reminding
us - and what seems natural and elegant to one person may well seem
kludge-ugly to another. There are lots of right ways. (And vastly more
wrong ways...)

While I don't generally disagree that setting a pointer to NULL after free()
is a good idea in simple cases, I think it's still just paranoid programming
where the paranoia lies against yourself.

We have better tools these days. Valgrind it, memcheck it, <insert whatever
tool is appropriate for your platform here> and use it. I've found that in a
lot of cases rather than relying on coding OCDs it can be more efficient to
just crank it through a competent external analyzer and find the problem
fast.

Caveats:

1. You might not have a decent tool on your platform.
2. You might be finding some obscure corner case (test suite anyone?)
3. You might be using NULL as a sentinel, so it's explicit setting is
warranted (but a general macro would not be).
4. You might think using an external tool is selling out to the man.
5. You might like your OCDs.
 
R

Richard Heathfield

Christopher Layne said:
While I don't generally disagree that setting a pointer to NULL after
free() is a good idea in simple cases, I think it's still just
paranoid programming where the paranoia lies against yourself.

Yes, you're probably right. On the other hand, I don't generally
experience pointer difficulties to the degree that some other regular
contributors to this newsgroup have suggested is the case for them (no
names, no pack drill). So I'm happy to be paranoid - it cuts down on
debugging time.

<snip>
 
R

Racaille

If a pointer is null, you can free it as often as you like. Try to
dereference it and you'll soon know what's wrong. Dereferencing or
freeing an invalid pointer has undefined and indeterminate results.

No, if you free a pointer multiple times, than the logic of your
program
is broken at its core, and you should probably rewrite the thing from
scratch.

People have put things in place to help you deal with that before the
things get bigger - for instance, free() may issue a diagnostic if
passed
an already freed pointer.

By setting it always to NULL after free(), you're defeating their
efforts.

Also, the value of the pointer may give someone who is debugging the
program
precious clue on where the value did come from - by setting it to
NULL,
you have made it indeterminate.

My advice is not to follow expert advices and never do things just
because
they're 'safe habits' - if setting a pointer to NULL doesn't serve a
specific
purpose (e.g. you want to pass it to a function where a NULL argument
means
something - default value/allocate a buffer/etc) then don't do it.
 
R

Richard Heathfield

Racaille said:
No, if you free a pointer multiple times, than the logic of your
program is broken at its core, and you should probably rewrite the
thing from scratch.

Possibly.

Also, the value of the pointer may give someone who is debugging the
program
precious clue on where the value did come from

No, because inspecting the value is not allowed. The value is
indeterminate, and inspecting it invokes undefined behaviour.
- by setting it to NULL, you have made it indeterminate.

No, by setting it to NULL, you have made it determinate!
My advice is not to follow expert advices

That's poor advice.
and never do things just because
they're 'safe habits' - if setting a pointer to NULL doesn't serve a
specific purpose (e.g. you want to pass it to a function where a NULL
argument means something - default value/allocate a buffer/etc) then
don't do it.

There *is* a specific purpose in setting a pointer to NULL - and that
purpose is to ensure that the value of the pointer is determinate and
can be tested meaningfully.
 
R

Racaille

No, because inspecting the value is not allowed. The value is
indeterminate, and inspecting it invokes undefined behaviour.


No, by setting it to NULL, you have made it determinate!

Please, let's stop this, it gets ridiculous. You still feign not to
get my point.
If you set it to NULL after very free(), then it could be just any
pointer
ever passed to free(), and so it is indeterminate from the point of
view of somebody trying to trace it.

I know there may be machines where just 'inspecting' a invalid pointer
(without dereferencing it) is not possible, but this is irrelevant,
since as a debugger writer I am free to use whatever machine
dependencies
I like in order to track down bugs, and I am free to take advantage of
pointers being just bitmaps/long integers is this makes things
simpler.
 
C

Christopher Layne

Racaille said:
Please, let's stop this, it gets ridiculous. You still feign not to
get my point.
If you set it to NULL after very free(), then it could be just any
pointer
ever passed to free(), and so it is indeterminate from the point of
view of somebody trying to trace it.

On the flipside, what IS wrong with setting it to NULL? It's a very distinct
state change and you're arguing that the lack of that state change somehow
will make debugging easier - which I don't agree with personally. It will
result in an immediate failure upon use. How is this slower (besides using
external tools) to track down than not setting it to NULL?

As a debugger writer you should be well aware of watchpoints, tracepoints,
etc. which aren't going to care if the pointer is set to NULL or not.
Unfortunately in a lot of cases they are extremely slow.
 
R

Richard Heathfield

Racaille said:
Please, let's stop this, it gets ridiculous.

Fine by me.
You still feign not to get my point.

I don't think you have one.
If you set it to NULL after very free(), then it could be just any
pointer ever passed to free(), and so it is indeterminate from the
point of view of somebody trying to trace it.

That's not what "indeterminate" means within the context of discussions
within this group. When we use the term "indeterminate", we mean that
the supposed value of an object has no meaning. NULL has a meaning -
it's a pointer value that is *guaranteed* not to point to any object,
and it can be meaningfully compared to another pointer value for
equality or inequality. And therein lies its value.
I know there may be machines where just 'inspecting' a invalid pointer
(without dereferencing it) is not possible, but this is irrelevant,

No, it isn't.
since as a debugger writer I am free to use whatever machine
dependencies

Yes, you are, but in *this* newsgroup we discuss machine-independent
code.
I like in order to track down bugs, and I am free to take advantage of
pointers being just bitmaps/long integers is this makes things
simpler.

You are also free to call dlopen() or SetWindowTitle(). That doesn't
make such things topical here.
 
R

Racaille

On the flipside, what IS wrong with setting it to NULL? It's a very distinct
state change and you're arguing that the lack of that state change somehow
will make debugging easier - which I don't agree with personally. It will

Setting it to NULL when not needed is a spurious state change, so it's
noise
and it makes debugging harder.
 
Y

Yevgen Muntyan

Richard said:
Racaille said:


Fine by me.


I don't think you have one.


That's not what "indeterminate" means within the context of discussions
within this group. When we use the term "indeterminate", we mean that
the supposed value of an object has no meaning. NULL has a meaning -
it's a pointer value that is *guaranteed* not to point to any object,
and it can be meaningfully compared to another pointer value for
equality or inequality. And therein lies its value.


No, it isn't.


Yes, you are, but in *this* newsgroup we discuss machine-independent
code.


You are also free to call dlopen() or SetWindowTitle(). That doesn't
make such things topical here.

There you go. Final argument in "how to write code and why" is "tools
you are talking about are off-topic here". Or was it about "how to
debug strictly conforming programs using only standard tools and
techniques"? Not that I get that "using junk pointers makes debugging
easier" concept, but either the whole discussion is off-topic here
(which it is, isn't it) or you got to admit the fact that people write
code in real life sometimes, using some non-standard tools (debugger!).

Yevgen
 
C

Christopher Layne

Racaille said:
Setting it to NULL when not needed is a spurious state change, so it's
noise
and it makes debugging harder.

No, it's an explicit state change. Which means when it is used, you know
exactly where to find THE ERROR. What is difficult for you to understand
about this non-obtuse approach?
 
M

Martin Ambuhl

This is Interesting..! I am just putting small code to check some
stuff.
[...]
char *p;
char*q;

p=(char *) malloc(100);

Are you being purposely obtuse? How many people need to tell you to
lose the obfuscating, error-prone, superfluous, and poor style cast of
the return value of malloc() before you pay attention?
/* I should do memset but ... */

No, you shouldn't, unless you just enjoy pointless waste of processing
time and pointless excessive typing.
strcpy(p,"raxit sheth");

q=p;

printf("\nP=%p : %s",p,p);
^^
but here you _should_ use a cast, since %p takes a pointer-to-void.
That 'void *' and 'char *' have the same form saves you here does not
change the fact that printing non-'void *' pointers with "%p" should be
cast.
printf("\nQ=%p :%s",q,q);
fflush(stdout);
free(p);
/* p=NULL; */

printf("\n AFTER FREE ");
printf("\nP=%p : %s",p,p);
^^
undefined behavior, since you are dereferencing a pointer not
pointing to allocated or declared memory. Your output is irrelevant.
 
S

santosh

There you go. Final argument in "how to write code and why" is "tools
you are talking about are off-topic here". Or was it about "how to
debug strictly conforming programs using only standard tools and
techniques"? Not that I get that "using junk pointers makes debugging
easier" concept, but either the whole discussion is off-topic here
(which it is, isn't it) or you got to admit the fact that people write
code in real life sometimes, using some non-standard tools (debugger!).

Well, there're literally millions of system dependencies and tools for
C programming. If they're all made topical here, focus (and expertise)
will be spread so thin as to be almost useless.

IMHO, NULL is better than an indeterminate value. In most situations
the assignment/s shouldn't take any significant time. As Richard Bos
pointed out, it may become tedious for large programs, but for small
to medium sized projects, it's one way to minimise scope for UB. It
helps in signalling mistakes, not in avoiding them.
 
Y

Yevgen Muntyan

santosh said:
Well, there're literally millions of system dependencies and tools for
C programming. If they're all made topical here, focus (and expertise)
will be spread so thin as to be almost useless.

I didn't say those tools are topical. Point is that if one talks
about why some way to write code is "better", then he got to accept
that some people write code which plays well with some tools, or
code which in any implementation-defined ways is better than other
code. Or something. You know, like such thing:

char *a = malloc(10);
char *b = malloc(10);
/* which one to free first, a or b? */

"Fragmentation" is off-topic here, but it's not an argument
why one should call free() in the same order as malloc() was
called. Or vice versa.

The right way is somewhere in between The Right Way (which doesn't
exist anyway) and Works For Me. And one can't simply say the latter
is wrong because it's off-topic.
IMHO, NULL is better than an indeterminate value. In most situations
the assignment/s shouldn't take any significant time. As Richard Bos
pointed out, it may become tedious for large programs, but for small
to medium sized projects, it's one way to minimise scope for UB. It
helps in signalling mistakes, not in avoiding them.

IMHO, it depends and it doesn't make much sense to talk about
which is better at all. Same thing as goto and multiple returns
from a function (even though some people believe there is one correct
answer).
 
C

Christopher Layne

Yevgen said:
IMHO, it depends and it doesn't make much sense to talk about
which is better at all. Same thing as goto and multiple returns
from a function (even though some people believe there is one correct
answer).

Here we go again with the "individual rights" preaching.
 
S

santosh

Yevgen said:
I didn't say those tools are topical. Point is that if one talks
about why some way to write code is "better", then he got to accept
that some people write code which plays well with some tools, or
code which in any implementation-defined ways is better than other
code. Or something. You know, like such thing:

Yes, that's why discussions on best practises in programming have been
so heated. Code that's optimised to work with certain other code is
perfectly fine. In fact, many popular pieces of software are precisely
built this way. But discussion of such code would be best taken to a
more specific group.

IMHO, it depends and it doesn't make much sense to talk about
which is better at all. Same thing as goto and multiple returns
from a function (even though some people believe there is one correct
answer).

You've expressed your HO and I've expressed my HO. We're at a
stalemate. What about calling quits on this discussion? It's a minor
issue and it's dragged on far enough.
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top