Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Function: free

0 views
Skip to first unread message

Brian Beharry

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

Should I be able to access memory already "freed up" by the "free" function?

This is what I've done on BSD(1.1.5.1) with gcc:

#include <stdio.h>

int main(void)
{
char *Ptr = NULL;

Ptr = (char *)malloc(sizeof(char));
*Ptr = 'b';
free(Ptr);


/* Shouldn't I get a segmentation fault on the next line? */
printf("%c\n", *Ptr);


return(0);

} /* End of main */

It turns out that I don't get a segmentation fault when I call printf.
I can print out what's at Ptr. Why don't I get the segmentation fault? It
seems as though the memory at Ptr wasn't deallocated. If that's true than I
don't understand the purpose of "free", or how to use it properly.

If anyone can help, thanks in advance!!! :)

______________________________________________________________________________
From: Brian Beharry
E-mail: bbeh...@uoguelph.ca

Gabor Egressy

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

Brian Beharry (bbeh...@uoguelph.ca) wrote:

: Should I be able to access memory already "freed up" by the "free" function?

: This is what I've done on BSD(1.1.5.1) with gcc:

: #include <stdio.h>

: int main(void)
: {
: char *Ptr = NULL;

: Ptr = (char *)malloc(sizeof(char));
: *Ptr = 'b';
: free(Ptr);


: /* Shouldn't I get a segmentation fault on the next line? */
: printf("%c\n", *Ptr);


: return(0);

: } /* End of main */

: It turns out that I don't get a segmentation fault when I call printf.
: I can print out what's at Ptr. Why don't I get the segmentation fault? It
: seems as though the memory at Ptr wasn't deallocated. If that's true than I
: don't understand the purpose of "free", or how to use it properly.

: If anyone can help, thanks in advance!!! :)

All free does is it puts the block of memory back in the free list. It
does not do anything else. Hence if you access that block before it is
allocated again by some other process you still can access it with the
pointer variable Ptr because Ptr is still holding the same address that
was returned by malloc. free does not set the value of Ptr to anything.
The purpose of free is to return memory no longer used by your process to
the operating system's free pool. Actually you could even free a null
pointer if you are using a compiler that conforms to the ANSI/ISO C
standard. Don't try that with a compiler that still uses K&R C though.

--
---------------------------------------------------------------------
Gabor Egressy gegr...@uoguelph.ca
Guelph, Ontario ga...@snowhite.cis.uoguelph.ca
Canada

No beast so fierce but knows some touch of pity
But I know none, And therefore am no beast
Richard III., William Shakespeare
vim : the best editor
---------------------------------------------------------------------

Chris Engebretson

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

In article <4rbfd0$e...@ccshst05.uoguelph.ca>, bbeh...@uoguelph.ca (Brian Beharry) writes:

|> Should I be able to access memory already "freed up" by the "free" function?

Should you be able to? Maybe. Should you try? Absolutely not.

|> #include <stdio.h>
|>
|> int main(void)
|> {
|> char *Ptr = NULL;
|>
|> Ptr = (char *)malloc(sizeof(char));
|> *Ptr = 'b';
|> free(Ptr);
|> /* Shouldn't I get a segmentation fault on the next line? */
|> printf("%c\n", *Ptr);
|> return(0);
|> } /* End of main */

Please read the FAQ before posting questions to this group; you would have
saved yourself some time, as this question is answered there.

For a lot of environments, you may very well find that the contents of
memory after a call to free() remain undisturbed. However, this behavior
is certainly not mandated/guaranteed by the Standard. Attempting to use
a region of memory after it has been freed invokes undefined behavior. In
the your case, you ended up getting the results that you were expecting (or
rather, that you were _not_ expecting.) :-)

With regards to the _value_ of Ptr, it is not changed by a call to free().
It still points to the same place, which is memory that has now been marked
again for possible use. However, again, the Standard says nothing about
the contents of that region after it has been freed; all that it says is that
it must _not_ be accessed. If you attempt to, you're responsible for
whatever repercussions might happen to arise.

In other words: Don't do it. :-)

--
/*-------------------------------------------------------------
Chris Engebretson // CSB - SED - Scientific Systems Development
United States Geological Survey - National Mapping Division
Mundt Federal Building, USGS EROS Data Center
Sioux Falls, SD 57198 http://edcwww.cr.usgs.gov/eros-home.html
email: enge...@edcserver1.cr.usgs.gov phone: 605-594-6829
-------------------------------------------------------------*/

Kurt J Lanza

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

bbeh...@uoguelph.ca (Brian Beharry) writes:


>Should I be able to access memory already "freed up" by the "free" function?

> This is what I've done on BSD(1.1.5.1) with gcc:

>#include <stdio.h>

>int main(void)
>{
> char *Ptr = NULL;

> Ptr = (char *)malloc(sizeof(char));
> *Ptr = 'b';
> free(Ptr);


> /* Shouldn't I get a segmentation fault on the next line? */
> printf("%c\n", *Ptr);


> return(0);

>} /* End of main */

> It turns out that I don't get a segmentation fault when I call printf.


>I can print out what's at Ptr. Why don't I get the segmentation fault? It
>seems as though the memory at Ptr wasn't deallocated. If that's true than I
>don't understand the purpose of "free", or how to use it properly.

I don't believe that the description of the normal free()
function says anything about removing the address(s) from your
legal address space. In fact, most implementations imply
exactly the opposite. The most common description I've seen
says that a recently freed area is guaranteed no to be
modified until the next call to malloc(), realloc() etc.
Why do you assume something never stated in a descritpion?
Hope this helps.

--
--
Kurt J. Lanza <k...@infor.com>

Janus

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

bbeh...@uoguelph.ca (Brian Beharry) wrote:

> Ptr = (char *)malloc(sizeof(char));
> *Ptr = 'b';
> free(Ptr);
>
>
> /* Shouldn't I get a segmentation fault on the next line? */
> printf("%c\n", *Ptr);

No you shouldn't - the memory at that address has been marked as no
longer in use by your program. but it's still there, and possibly
still has the 'b' you wrote to it. So your printf() will often seem to
work.

Then again - your OS is multitasking then there's always the chance
that another process will "grab" that byte before your printf() gets
to it, so then your program is trying to use memory that belongs to
another program, and yours'll be crashed. Such code running in a
single-tasking environment is more likely to not crash.

Of course the result of using freed pointers should result in
"undefined" behaviour, and "undefined" is best defined (:-) as "it
will always look like it works, until it's important that it does, or
until you post it to comp.lang.c".

Bye from
Janus at Kerry, Ireland
email : j...@iol.ie
WWW : http://www.iol.ie/~jab


Dan Pop

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

In <4rbfd0$e...@ccshst05.uoguelph.ca> bbeh...@uoguelph.ca (Brian Beharry) writes:


>Should I be able to access memory already "freed up" by the "free" function?

The question is answered in the FAQ. You should have read it _before_
posting.

>#include <stdio.h>
>
>int main(void)
>{
> char *Ptr = NULL;
>
> Ptr = (char *)malloc(sizeof(char));

I can't see any declaration for malloc, and malloc definitely doesn't
return int. Your code invokes undefined behaviour.

> *Ptr = 'b';
> free(Ptr);
>
> /* Shouldn't I get a segmentation fault on the next line? */
> printf("%c\n", *Ptr);

Nope. Dereferencing a pointer pointing to freed memory results in
undefined behaviour, and this really means undefined behaviour, i.e.
no particular behaviour is required. You _could_ get a segmentation
fault, but you also could have demons flying out of your nose.

On a more practical note: on most implementations, you won't get a
segmentation fault, the freed memory still belongs to your program (even
if you aren't allowed to access it yourself). However, if you link in
a debugging library like ElectricFence, your code will generate a
segmentation fault.

Dan
--
Dan Pop
CERN, CN Division
Email: Dan...@cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland

Lawrence Kirby

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

In article <4rbfd0$e...@ccshst05.uoguelph.ca>
bbeh...@uoguelph.ca "Brian Beharry" writes:

>
>Should I be able to access memory already "freed up" by the "free" function?
>

> This is what I've done on BSD(1.1.5.1) with gcc:
>

>#include <stdio.h>
>
>int main(void)
>{
> char *Ptr = NULL;
>
> Ptr = (char *)malloc(sizeof(char));

> *Ptr = 'b';
> free(Ptr);
>
>
> /* Shouldn't I get a segmentation fault on the next line? */
> printf("%c\n", *Ptr);
>
>

> return(0);
>
>} /* End of main */
>
> It turns out that I don't get a segmentation fault when I call printf.

You might but there is no guarantee that you will. Whern you access memory
that has been freed you invoke undefined behavour which means that
anything can happen including getting a seg fault or not getting a seg fault.

>I can print out what's at Ptr. Why don't I get the segmentation fault? It
>seems as though the memory at Ptr wasn't deallocated. If that's true than I
>don't understand the purpose of "free", or how to use it properly.

You misunderstand what is meant by "deallocated". The memory is still
there (probably) but it is marked as available for subsequent rallocation
to you by malloc. In the meantime the results of your program accessing it
are unpredictable.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

The Amorphous Mass

unread,
Jul 2, 1996, 3:00:00 AM7/2/96
to

On 2 Jul 1996, Brian Beharry wrote:

> Should I be able to access memory already "freed up" by the "free" function?

No.

> This is what I've done on BSD(1.1.5.1) with gcc:
>
> #include <stdio.h>
> int main(void)
> {
> char *Ptr = NULL;
>
> Ptr = (char *)malloc(sizeof(char));

FYI this is equivalent to Ptr = malloc(1);
If you lose the cast then the compiler will point out that you're
trying to assign an int to a char *. You forgot to #include <stdlib.h>
so the compiler assumes that malloc() returns an int. This can result in
Bad Things(TM) happening.

> *Ptr = 'b';
> free(Ptr);
>
> /* Shouldn't I get a segmentation fault on the next line? */
> printf("%c\n", *Ptr);

Most operating systems only protect memory in segments or partitions,
because they assume that the users want more than 10% of the CPU's
time available to their processes. :-) If you access memory you haven't
allocated, or run off the end of an array, there is *no* guarantee that
you will get an error for it, on any OS -- the OS will only flag an error
if you try to access memory that your process isn't allowed to access.

> return(0);
>
> } /* End of main */
>
> It turns out that I don't get a segmentation fault when I call printf.

> I can print out what's at Ptr. Why don't I get the segmentation fault? It
> seems as though the memory at Ptr wasn't deallocated. If that's true than I
> don't understand the purpose of "free", or how to use it properly.

malloc()/free() often don't immediately allocate and deallocate
memory. For example, a conforming version of malloc() can allocate 1MB
the first time it's called and set up its own heap in that memory, so
that further calls to malloc() and free() are just a matter of updating data
structures and juggling pointers around, at least until the 1MB is used
up. So in a technical sense a free()'d pointer *could* still point to
valid memory. You can't count on any implementation using that method,
though, so it's very poor practice to take advantage of it.
To answer your last question, C assumes that you know what you're
doing, and it does *not* correct your every misstep. It is up to you to
make sure that you aren't doing things like dereferencing uninitialized,
NULL, or free()'d pointers, or running off the end of arrays. Someone a
while back posted a password-reading program that, when he ran it, read
up to 3000 characters before blowing up, and it "worked" by writing
through an unitialized pointer that just happened to point to the
beginning of about 3K of unused memory! The lesson is that just because
the code compiles and even runs "correctly" doesn't mean that it's good
or working code. You're gambling, and this time the computer let you win.
Hope this helps,

/**James Robinson***********************
"An important goal of almost every graphics program is to draw pictures on
the screen." -- Neider, Davis & Woo, _OpenGL_Programming_Guide_, Chapter 10
*************james-r...@uiowa.edu**/

Dan Pop

unread,
Jul 3, 1996, 3:00:00 AM7/3/96
to

In <4rbimc$1...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:

>All free does is it puts the block of memory back in the free list. It
>does not do anything else. Hence if you access that block before it is
>allocated again by some other process you still can access it with the
>pointer variable Ptr because Ptr is still holding the same address that
>was returned by malloc. free does not set the value of Ptr to anything.
>The purpose of free is to return memory no longer used by your process to
>the operating system's free pool.

All this text is a work of pure fiction, with no support in the definition
of the C language (and I have yet to see a single implementation behaving
as described above). Treat it as such.

Its author is kindly advised to avoid posting his own personal opinions
disguised as facts.

Gabor Egressy

unread,
Jul 3, 1996, 3:00:00 AM7/3/96
to

Dan Pop (Dan...@cern.ch) wrote:

: In <4rbimc$1...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:

: >All free does is it puts the block of memory back in the free list. It
: >does not do anything else. Hence if you access that block before it is
: >allocated again by some other process you still can access it with the
: >pointer variable Ptr because Ptr is still holding the same address that
: >was returned by malloc. free does not set the value of Ptr to anything.
: >The purpose of free is to return memory no longer used by your process to
: >the operating system's free pool.

: All this text is a work of pure fiction, with no support in the definition
: of the C language (and I have yet to see a single implementation behaving
: as described above). Treat it as such.

: Its author is kindly advised to avoid posting his own personal opinions
: disguised as facts.

I did not disguise what I wrote as fact. Anything anybody says here,
unless supported by a quote from the standard should be taken with a
grain of salt. What I said is certainly a simplified version of what
happens. I am no OS expert, and there are many different ways of managing
memory. What I was trying to say, unfortunately I don't always succeed as
English is a second language to me, is that free does not in any way
alter the pinter variable that was freed. I think that is what the author
of the question was surprised about. I suppose he had somehow hoped that
after using free that somehow he would receive a warning or something
about using a pointer that is no longer holding an address that should be
dereferenced.
However, I am glad that I post even if I am wrong because of the
feedback I get from you or Lawrence Kirby. It's nice to learn from people
who know a lot more than I do.

: Dan : --


: Dan Pop
: CERN, CN Division
: Email: Dan...@cern.ch
: Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland

--

Dan Pop

unread,
Jul 3, 1996, 3:00:00 AM7/3/96
to

In <4re5pk$q...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:

>Dan Pop (Dan...@cern.ch) wrote:
>: In <4rbimc$1...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:
>
>: >All free does is it puts the block of memory back in the free list. It
>: >does not do anything else. Hence if you access that block before it is
>: >allocated again by some other process you still can access it with the
>: >pointer variable Ptr because Ptr is still holding the same address that
>: >was returned by malloc. free does not set the value of Ptr to anything.
>: >The purpose of free is to return memory no longer used by your process to
>: >the operating system's free pool.
>
>: All this text is a work of pure fiction, with no support in the definition
>: of the C language (and I have yet to see a single implementation behaving
>: as described above). Treat it as such.
>
>: Its author is kindly advised to avoid posting his own personal opinions
>: disguised as facts.
>
>I did not disguise what I wrote as fact. Anything anybody says here,
>unless supported by a quote from the standard should be taken with a
>grain of salt. What I said is certainly a simplified version of what
>happens.

No, it isn't. On all the implementations I've ever seen, free() never
returns anything to the "operating system's free pool", as you claimed
above. I believe that the standard itself forbids such a behaviour,
but not everybody agrees on this interpretation.

>I am no OS expert, and there are many different ways of managing
>memory.

All of them being irrelevant in a newsgroup dedicated to a programming
language. All that matters here is what the language definition says
about the issue discussed.

>What I was trying to say, unfortunately I don't always succeed as
>English is a second language to me,

And a third language to me.

>is that free does not in any way alter the pinter variable that was freed.

Again, this statement is only your opinion. The language definition doesn't
prevent the compiler from altering the value of the pointer variable passed
as argument to free() (by using "compiler magic"). The exact wording of
the standard is:

The value of a pointer that refers to freed space is indeterminate.

>I think that is what the author of the question was surprised about.

I don't. I think he expected the attempt to access freed memory to
generate a segmentation fault. While this is not the usual behaviour,
I do use one implementation which does exactly this.

>I suppose he had somehow hoped that
>after using free that somehow he would receive a warning or something
>about using a pointer that is no longer holding an address that should be
>dereferenced.

I.e. something like this:

ues5:~/tmp 244> cat test.c
#include <stdlib.h>

main()
{
char *p = malloc(1);
if (p) {
*p = 'a';
free(p);
putchar(*p);
}
return 0;
}
ues5:~/tmp 245> gcc -g test.c -lefence
ues5:~/tmp 246> ./a.out

Electric Fence 2.0.5 Copyright (C) 1987-1995 Bruce Perens.
Segmentation fault (core dumped)
ues5:~/tmp 247> gdb a.out core
<snip>
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/shlib/libc.so...done.
#0 0x1200019d4 in main () at test.c:9
9 putchar(*p);

As you see, this can actually happen. And the language definition
definitely allows this behaviour (like any other, because we're dealing
with a case of undefined behaviour).

>However, I am glad that I post even if I am wrong because of the
>feedback I get from you or Lawrence Kirby. It's nice to learn from people
>who know a lot more than I do.

But it's not nice at all to confuse people who know less than you do.

Jens Schweikhardt

unread,
Jul 4, 1996, 3:00:00 AM7/4/96
to

In article <4re5pk$q...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:
+Dan Pop (Dan...@cern.ch) wrote:
+: In <4rbimc$1...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:
+
+: >All free does is it puts the block of memory back in the free list. It
+: >does not do anything else. Hence if you access that block before it is
+: >allocated again by some other process you still can access it with the
+: >pointer variable Ptr because Ptr is still holding the same address that
+: >was returned by malloc. free does not set the value of Ptr to anything.
+: >The purpose of free is to return memory no longer used by your process to
+: >the operating system's free pool.

Depends on the malloc/free implementation, as do many things.
You have to distinguish between the OS memory pool (eg the virtual
memory that the OS shares between _all_ processes) and the memory
that malloc took from some memory region given to your process by the OS.
It is essential to have understood that these are separate types of
memory. For many implementations the last sentence in the above paragraph
is *wrong*! It's not returned to the OS pool, but to the malloc pool.

#ifdef SLIGHLY_OFFTOPIC_IMPLEMENTATION_ISSUES

You may think that every malloc (at least on unix) gets its memory
from the system by calling brk/sbrk to increase the program's
address space. Many do, and many never give that memory back to the
OS. Such an implementation of malloc may well leave any freed block
untouched upto the next malloc/calloc/realloc (which may happen even
in a library function, like fopen). But why would you want to count on
that? Tomorrow you plug in the newest gnu malloc and you program bombs.
Why?
Suppose malloc gets its memory not by calling sbrk, but uses memory mapped
IO, e.g. mapping portions of /dev/zero into the process address space.
Not too far fetched in my eyes. Giving back memory that was memory mapped
is easy, just call munmap. A clever (or may I say, resource friendly and
cooperative) malloc implementation would return a page of memory _immediately_
as you free the last block in it. So

free (Ptr); /* unmaps the page Ptr points to */
*Ptr = 0;

will segfault right away.
#endif SLIGHLY_OFFTOPIC_IMPLEMENTATION_ISSUES

+: All this text is a work of pure fiction, with no support in the definition
+: of the C language (and I have yet to see a single implementation behaving
+: as described above). Treat it as such.
+
+: Its author is kindly advised to avoid posting his own personal opinions
+: disguised as facts.
+
+I did not disguise what I wrote as fact. Anything anybody says here,
+unless supported by a quote from the standard should be taken with a
+grain of salt.

I bet it won't take long until you hear Dan quoting the Standard.
So I won't.

+What I said is certainly a simplified version of what
+happens. I am no OS expert,

Neither am I. And exactly that is the reason why I do not assume
_anything_ about _any_ malloc/free implementation, except what the
Standard tells me. It does NOT say

"All free does is it puts the block of memory back in the free list. It
does not do anything else."

so I don't count on "It does not do anything else." If I had my may
writing free(), it would surprise you!

+ and there are many different ways of managing
+memory. What I was trying to say, unfortunately I don't always succeed as
+English is a second language to me, is that free does not in any way
+alter the pointer variable that was freed.

You can't be sure. Would you bet your life on it? Would you take a flight
in a Space Shuttle that relied on free() not altering the block?
Anyone who makes assumptions about implementation issues beyond his
control should be test riding the prototype of the vehicle that uses
his/her software in the emergency rescue system.

+I think that is what the author
+of the question was surprised about. I suppose he had somehow hoped that
+after using free that somehow he would receive a warning or something
+about using a pointer that is no longer holding an address that should be
+dereferenced.

A good lint will complain. Lclint for example does.

+However, I am glad that I post even if I am wrong because of the
+feedback I get from you or Lawrence Kirby. It's nice to learn from people
+who know a lot more than I do.

You are a nice guy. Everybody here would love you even more
if you would turn your postings into questions instead of statements.
Next time you may ask

"I heard from <my girlfriend, bill clinton, elvis, the NSA> that


All free does is it puts the block of memory back in the free list.

Sounds unbelievable. Is it true?"

instead of asserting

"All free does is it puts the block of memory back in the free list."

Jens
--
SIGSIG -- signature too long (core dumped)

Gabor Egressy

unread,
Jul 4, 1996, 3:00:00 AM7/4/96
to

Jens Schweikhardt (schw...@rubin.noc.dfn.de) wrote:

: #ifdef SLIGHLY_OFFTOPIC_IMPLEMENTATION_ISSUES

: instead of asserting

Point taken. Next time I won't make assertions about things I am not a
100% on. Actually when I said free pool I actually meant the free list
managed by malloc. Would that have been better?

: Jens


: --
: SIGSIG -- signature too long (core dumped)

--


---------------------------------------------------------------------
Gabor Egressy gegr...@uoguelph.ca
Guelph, Ontario ga...@snowhite.cis.uoguelph.ca
Canada

No beast so fierce but knows some touch of pity
But I know none, And therefore am no beast
Richard III., William Shakespeare
vim : the best editor

ftp.fu-berlin.de/misc/editors/vim/beta-test
---------------------------------------------------------------------

Phil Howard

unread,
Jul 5, 1996, 3:00:00 AM7/5/96
to

On Wed, 3 Jul 1996 23:20:26 GMT Dan Pop (Dan...@cern.ch) wrote:

| In <4re5pk$q...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:

| No, it isn't. On all the implementations I've ever seen, free() never
| returns anything to the "operating system's free pool", as you claimed
| above. I believe that the standard itself forbids such a behaviour,
| but not everybody agrees on this interpretation.

I'm reading the standard now (7.10.3.2) and see nothing that forbids
returning memory resources to the operating system's free pool. While
I have not seen any system that does so, that could be because I have
done all my C programming on virtual memory systems where this would
not generally be done, not because the language prohibits it. Oh I did
do a little bit of C programming on DOS once, but I didn't explore its
memory allocation.


| >I am no OS expert, and there are many different ways of managing
| >memory.
|
| All of them being irrelevant in a newsgroup dedicated to a programming
| language. All that matters here is what the language definition says
| about the issue discussed.

Which neither requires nor forbids it that I can see.


| Again, this statement is only your opinion. The language definition doesn't
| prevent the compiler from altering the value of the pointer variable passed
| as argument to free() (by using "compiler magic"). The exact wording of
| the standard is:
|
| The value of a pointer that refers to freed space is indeterminate.

Unfortunately, this is one of those vaguenesses in the language. While
copies of the pointer made before free() is called on it would be expected
to retain their original bit pattern, the "value" could be distinctly
different in terms of interpreting that bit pattern as a pointer because
of the indeterminate effects of doing so.

If you do:

free( p = malloc( 16 ) );

don't expect "p" to have the NULL value. It might, if malloc() failed,
otherwise it will have a _valueless_ bit pattern.


| >I think that is what the author of the question was surprised about.
|
| I don't. I think he expected the attempt to access freed memory to
| generate a segmentation fault. While this is not the usual behaviour,
| I do use one implementation which does exactly this.

Agreed.


| >However, I am glad that I post even if I am wrong because of the

| >feedback I get from you or Lawrence Kirby. It's nice to learn from people

| >who know a lot more than I do.
|

| But it's not nice at all to confuse people who know less than you do.

However, I must agree with Gabor Egressy on this. The reason is not
that I support the idea of confusing people, as his and other like posts
might do, but because it actually takes that kind of tact to illicit
authoritative responses that often (not just in comp.lang.c but also
everywhere else) ignore mere questions. I have in fact found from
real experience that posting a question more likely goes unanswered
and posting a false assertion will get a response (-: and often a flame
which does seem to melt ice well :-). It shouldn't be that way and I
wish it were different. But it hasn't changed yet.

--
Phil Howard KA9WGN +-------------------------------------------------------+
Linux Consultant | "Adolf Hitler was OK at the beginning, but then he |
Milepost Services | went too far". --Marge Schott --World History |
ph...@milepost.com +-------------------------------------------------------+

Dan Pop

unread,
Jul 5, 1996, 3:00:00 AM7/5/96
to

In <4rhojg$o...@sunsrv12.clr.com> ph...@milepost.com (Phil Howard) writes:

>On Wed, 3 Jul 1996 23:20:26 GMT Dan Pop (Dan...@cern.ch) wrote:
>
>| In <4re5pk$q...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy) writes:
>
>| No, it isn't. On all the implementations I've ever seen, free() never
>| returns anything to the "operating system's free pool", as you claimed
>| above. I believe that the standard itself forbids such a behaviour,
>| but not everybody agrees on this interpretation.
>
>I'm reading the standard now (7.10.3.2) and see nothing that forbids
>returning memory resources to the operating system's free pool.

The key phrase is:

The free function causes the space pointed to by ptr to be
deallocated, that is, made available for further allocation.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the memory is returned to the OS free memory pool, it might give it
to another process, thus the memory may not be available for further
allocation to the program that called free() in the first place.

The standard describes the behaviour of a program, not of an entire
system, so the memory freed by a program should be available to that
program for further allocation.

>While
>I have not seen any system that does so, that could be because I have
>done all my C programming on virtual memory systems where this would
>not generally be done, not because the language prohibits it. Oh I did
>do a little bit of C programming on DOS once, but I didn't explore its
>memory allocation.

DOS behaves the same way as other systems WRT malloc/free. The memory
freed still belongs to the program's heap.

>| Again, this statement is only your opinion. The language definition doesn't
>| prevent the compiler from altering the value of the pointer variable passed
>| as argument to free() (by using "compiler magic"). The exact wording of
>| the standard is:
>|
>| The value of a pointer that refers to freed space is indeterminate.
>
>Unfortunately, this is one of those vaguenesses in the language.

I can't see anything vague here. It's crystal clear: once you call free,
anything can happen with the values of all the pointers pointing into
the memory block that was freed. This is the only possible interpretation
of that statement.

>While
>copies of the pointer made before free() is called on it would be expected
>to retain their original bit pattern,

This expectation is definitely not based on the text of the standard.

>the "value" could be distinctly
>different in terms of interpreting that bit pattern as a pointer because
>of the indeterminate effects of doing so.

Any attempt to interpret that bit pattern as a pointer results in undefined
behaviour. So, it makes very little sense to talk about it.

>If you do:
>
> free( p = malloc( 16 ) );
>
>don't expect "p" to have the NULL value. It might, if malloc() failed,
>otherwise it will have a _valueless_ bit pattern.

After doing that, you can't expect _anything_ about p. The only operation
that may be performed with the value of p without invoking undefined
behaviour is a memcpy/memmove(dest, &p, sizeof p), but there are people
who don't agree even on this one. Even a plain assignment (q = p)
invokes undefined behaviour.

Lawrence Kirby

unread,
Jul 5, 1996, 3:00:00 AM7/5/96
to

In article <4rhojg$o...@sunsrv12.clr.com> ph...@milepost.com "Phil Howard" writes:

>On Wed, 3 Jul 1996 23:20:26 GMT Dan Pop (Dan...@cern.ch) wrote:
>
>| In <4re5pk$q...@ccshst05.uoguelph.ca> gegr...@uoguelph.ca (Gabor Egressy)
> writes:
>
>| No, it isn't. On all the implementations I've ever seen, free() never
>| returns anything to the "operating system's free pool", as you claimed
>| above. I believe that the standard itself forbids such a behaviour,
>| but not everybody agrees on this interpretation.
>
>I'm reading the standard now (7.10.3.2) and see nothing that forbids
>returning memory resources to the operating system's free pool.

The question is how you interpret:

"The free function causes the space
pointed to by ptr to be deallocated, that is, made available for further
allocation."

Since the standard is only cencerned with the execution environment of
a single program this imples the space must be made available for further
allocation to *this* program. Systems which return the space to the
"operating system" in general can't guarantee that.

Of course this view is open to debate! :-)

There is also the question of whether a strictly conforming program can
tell the difference.

Dan Pop

unread,
Jul 5, 1996, 3:00:00 AM7/5/96
to

>Since the standard is only cencerned with the execution environment of
>a single program this imples the space must be made available for further
>allocation to *this* program. Systems which return the space to the
>"operating system" in general can't guarantee that.
>
>Of course this view is open to debate! :-)
>
>There is also the question of whether a strictly conforming program can
>tell the difference.

Of course it can:

#include <stdlib.h>

#define SIZE 32767

int main(void)
{
char *p = malloc(SIZE);
if (p) {
free(p);
/* waste some time */
if ((p = malloc(SIZE)) == NULL) puts("this implementation is broken");
}
return 0;

Douglas Martin

unread,
Jul 5, 1996, 3:00:00 AM7/5/96
to

In article <4re5pk$q...@ccshst05.uoguelph.ca>, gegr...@uoguelph.ca (Gabor
Egressy) wrote:


>
> I did not disguise what I wrote as fact. Anything anybody says here,

> unless supported by a quote from the standard should be taken with a

> grain of salt. What I said is certainly a simplified version of what
> happens. I am no OS expert, and there are many different ways of managing

> memory. What I was trying to say, unfortunately I don't always succeed as

> English is a second language to me, is that free does not in any way

> alter the pinter variable that was freed. I think that is what the author

> of the question was surprised about. I suppose he had somehow hoped that

> after using free that somehow he would receive a warning or something

> about using a pointer that is no longer holding an address that should be

> dereferenced.


> However, I am glad that I post even if I am wrong because of the
> feedback I get from you or Lawrence Kirby. It's nice to learn from people
> who know a lot more than I do.
>

What you said about the pointer itself (that it is not changed) is
correct; that is clear from the definition of C (since function parameters
get passed by value, the pointer itself can't possibly be changed).

However, where you went too far was to assume the implementation of memory
management that you are most familiar with is the implementation that
everyone uses. As I'm sure you've noticed, OS-specific and
compiler-specific questions and answers tend to get thoroughly flamed in
this group.

Just because the value of the pointer passed to free doesn't itself get
changed, there's nothing in theory stopping the OS from adjusting its
tables so that the value no longer is a valid memory address (i.e. so that
a reference to that address causes an error). The fact that it rarely
happens that way doesn't mean that it can never happen that way.

--
Douglas Martin d_ma...@biomira.com
Clinical Support Programmer dma...@planet.eon.net
Biomira Inc.
2011 - 94 St. Edmonton

Lawrence Kirby

unread,
Jul 6, 1996, 3:00:00 AM7/6/96
to

In article <danpop.8...@news.cern.ch> Dan...@cern.ch "Dan Pop" writes:

>In <836566...@genesis.demon.co.uk> Lawrence Kirby <fr...@genesis.demon.co.uk>
> writes:
>
>>Since the standard is only cencerned with the execution environment of
>>a single program this imples the space must be made available for further
>>allocation to *this* program. Systems which return the space to the
>>"operating system" in general can't guarantee that.
>>
>>Of course this view is open to debate! :-)
>>
>>There is also the question of whether a strictly conforming program can
>>tell the difference.
>
>Of course it can:
>
>#include <stdlib.h>
>
>#define SIZE 32767
>
>int main(void)
>{
>char *p = malloc(SIZE);
>if (p) {
> free(p);
> /* waste some time */
> if ((p = malloc(SIZE)) == NULL) puts("this implementation is broken");
> }
>return 0;
>}

I don't think the standard text is strong enough to guarantee that.

There is nothing in 7.10.3.3 that prevents malloc returning a null
pointer whenever it likes. Certainly 7.10.3 says "If the space cannot
be allocated, a null pointer is returned", however it doesn't define the
circumstances where "space cannot be allocated". In particular it does
not specify how the heap is managed and what management overhead there
may be. There's nothing preventing data allocated from a previously
freed block requiring more space overhead than an initial allocation.

If you were to argue that the whole block must be available for further
allocation then the consequence would be that you would be guaranteed
to be able to individually allocate 32767 single byte objects which
I think that most would accept is not guaranteed.

Dan Pop

unread,
Jul 7, 1996, 3:00:00 AM7/7/96
to

>In article <danpop.8...@news.cern.ch> Dan...@cern.ch "Dan Pop" writes:
>
>>In <836566...@genesis.demon.co.uk> Lawrence Kirby <fr...@genesis.demon.co.uk>
>> writes:
>>
>>>Since the standard is only cencerned with the execution environment of
>>>a single program this imples the space must be made available for further
>>>allocation to *this* program. Systems which return the space to the
>>>"operating system" in general can't guarantee that.
>>>
>>>Of course this view is open to debate! :-)
>>>
>>>There is also the question of whether a strictly conforming program can
>>>tell the difference.
>>
>>Of course it can:
>>
>>#include <stdlib.h>
>>
>>#define SIZE 32767
>>
>>int main(void)
>>{
>>char *p = malloc(SIZE);
>>if (p) {
>> free(p);
>> /* waste some time */
>> if ((p = malloc(SIZE)) == NULL) puts("this implementation is broken");
>> }
>>return 0;
>>}
>
>I don't think the standard text is strong enough to guarantee that.
>

>may be. There's nothing preventing data allocated from a previously
>freed block requiring more space overhead than an initial allocation.

If not all my 32767 bytes can be further allocated, the same way they
were initially allocated, the implementation violates the standard (but
see the end of this article).

>If you were to argue that the whole block must be available for further
>allocation then the consequence would be that you would be guaranteed
>to be able to individually allocate 32767 single byte objects which
>I think that most would accept is not guaranteed.

I can't see how you reached that conclusion. The whole block must be
available for allocation as a single block, not as multiple blocks whose
sizes add up to the size of the initial block.

The fact that I was intially able to allocate _one_ memory block only
guarantees that I should be able to allocate _one_ memory block of a
size at most as large as the size of the initial block. The implementation
needs not support more than one dynamically allocated memory block, but
the initial successful allocation should guarantee the possibility to
allocate one block of that size.

If the implementation doesn't support any dynamic memory allocation, or
only the allocation of blocks smaller than 32767, then my program will
not be able to detect whether it's broken or not. The most interesting
fact is that an implementation where malloc ALWAYS returns a null pointer
is OK :-)

As I mentioned upthread, the text of the standard can be interpreted in
more than one way.

Dann Corbit

unread,
Jul 8, 1996, 3:00:00 AM7/8/96
to

> Lawrence Kirby <fr...@genesis.demon.co.uk> wrote in article
<836566...@genesis.demon.co.uk>...
{snip}

> In article <4rhojg$o...@sunsrv12.clr.com> ph...@milepost.com "Phil Howard"
writes:
> >I'm reading the standard now (7.10.3.2) and see nothing that forbids
> >returning memory resources to the operating system's free pool.
>
> The question is how you interpret:
>
> "The free function causes the space
> pointed to by ptr to be deallocated, that is, made available for
further
> allocation."
>
> Since the standard is only cencerned with the execution environment of
> a single program this imples the space must be made available for
further
> allocation to *this* program. Systems which return the space to the
-----------------------^^^^
I don't see how you can assume this (though I recognize that you know
a LOT more about ANSI C implementations that I do).

> "operating system" in general can't guarantee that.

{snip}

It seems to me that such an implementation would be most inefficient.
Suppose that a program that runs for a long time needs a large block
of memory on startup. A conforming compiler by this definition would
have to keep that amount of memory available to the program at all
times. If the program does not need the memory, it is preventing other
programs that need the resource from obtaining it for no reason other
than it might possibly need a large block later.

If the compiler follows what is printed exactly (but not what is assumed)
how could it possibly be said not to be in compliance?

Al Bowers

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

> Dan Pop (Dan...@cern.ch) wrote:
>
> The key phrase is:

>
> The free function causes the space pointed to by ptr to be
> deallocated, that is, made available for further allocation.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Running MS-DOS and Quick-C, I wanted to see if in fact the free function
made available the memory for further allocation. I coded a loop that
was endless unless malloc failed. First omitting the free function, the
loop failed after five cycles. Including the free function in the loop
caused the loop to cycle forever. Damn, it is still cycling. Actually,
I had to use Control-C to break the loop. Wouldn't this indicate
that the free function caused the space pointed to by ptr to be deallocated
and made available for further allocation?

#include <stdio.h>

#define BUFSIZE 10000

int main()
{
int x = 1, i = 0;
char *ptr;

while(x)
{
if(ptr = (char *) malloc(BUFSIZE))
{
printf("Press CONTROC-C to exit. %d\n",i);
i++;
/* free(ptr); */
}
else
{
printf("\nReallocation failed");
exit(0);
}
}
}


--
Al Bowers
Tampa, FL
mailto:abo...@combase.com
http:www.gate.net/~abowers/index.html

Szu-Wen Huang

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

Dan Pop (Dan...@cern.ch) wrote:

: The key phrase is:

: The free function causes the space pointed to by ptr to be
: deallocated, that is, made available for further allocation.
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

: If the memory is returned to the OS free memory pool, it might give it
: to another process, thus the memory may not be available for further
: allocation to the program that called free() in the first place.

: The standard describes the behaviour of a program, not of an entire
: system, so the memory freed by a program should be available to that
: program for further allocation.

[snip]

While your interpretation is certainly logical, I doubt that the
writer of that line meant the strict observance you propose. For
one, it gains no advantage. When I call malloc(), I don't expect
to get a specific block, so whether a free()d block was returned to
the OS or given back to me next time I call malloc() is really
immaterial. I think you're reading too much into that line.

Dan Pop

unread,
Jul 12, 1996, 3:00:00 AM7/12/96
to

What is really material is whether you can expect to get back memory
you've free'd or not. If the memory is returned to the operating
system, you have no guarantee that you'll be able to get it back,
when needed, via another malloc/calloc/realloc call.

If my interpretation is dismissed, then this is a strictly compliant
implementation of free:

void free(void *p) {}

It doesn't make any byte available for further allocation, but no
strictly conforming program will be able to detect this, hence the
implementation doesn't violate the standard.

BTW, all real life implementations _that I know of_ behave according to
my interpretation. It's trivial to convince yourself of this on a Unix
system, with the following program:

#include <stdlib.h>
main()
{
char *p = malloc(1000000);
free(p);
for (;;) ;
}

Start it and check the process size, before killing it. Comment out the
malloc and free calls and repeat the exercise.

Kevin D. Quitt

unread,
Jul 12, 1996, 3:00:00 AM7/12/96
to

On Thu, 11 Jul 1996 10:35:55 -0400, Al Bowers <abo...@combase.com> wrote:

>> Dan Pop (Dan...@cern.ch) wrote:
>>
>> The key phrase is:
>>
>> The free function causes the space pointed to by ptr to be
>> deallocated, that is, made available for further allocation.
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>Running MS-DOS and Quick-C, I wanted to see if in fact the free function
>made available the memory for further allocation.

It's nice to know that Quick-C is the authoritative source for what is and
isn't legal in C. Think of the money I could have saved by not buying all
those worthless documents from ANSI/ISO. I could just cry.


> I coded a loop that
>was endless unless malloc failed. First omitting the free function, the
>loop failed after five cycles. Including the free function in the loop
>caused the loop to cycle forever. Damn, it is still cycling. Actually,
>I had to use Control-C to break the loop. Wouldn't this indicate
>that the free function caused the space pointed to by ptr to be deallocated
>and made available for further allocation?

So what? That was never the question. The question was whether the memory
free was made available to the Operating System, or merely to the program.
Dan's point is that the spec says nothing about releasing memory to the OS;
generally that doesn't happen until the program terminates, but whatever the
case, it has nothing to do with C. Your program is incapable of
distinguishing between the two cases, and is therefore useless, except to
possibly show that Quick-C's library doesn't have certain eggregious bugs in
the malloc/free routines.

--
#include <standard_disclaimer.h> http://emoryi.jpl.nasa.gov/
_
Kevin D Quitt USA 91351-4454 96.37% of all statistics are made up
Per the FCA, this email address may not be added to any commercial mail list

Bob Nelson

unread,
Jul 14, 1996, 3:00:00 AM7/14/96
to

Kevin D. Quitt (k...@emoryi.jpl.nasa.gov) wrote:
> On Thu, 11 Jul 1996 10:35:55 -0400, Al Bowers <abo...@combase.com> wrote:
> >> Dan Pop (Dan...@cern.ch) wrote:
> >> The key phrase is:
> >>
> >> The free function causes the space pointed to by ptr to be
> >> deallocated, that is, made available for further allocation.
> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >Running MS-DOS and Quick-C, I wanted to see if in fact the free function
> >made available the memory for further allocation.

> It's nice to know that Quick-C is the authoritative source for what is and
> isn't legal in C. Think of the money I could have saved by not buying all
> those worthless documents from ANSI/ISO. I could just cry.

IMHO, K&R2 (p. 4) incorrectly give creedence to such thoughts: "In
cases of doubt, however, the standard and one's own compiler remain
the final authorities on the language."

--
=============================================================================
Bob Nelson: Dallas, Texas, U.S.A. - bne...@netcom.com
linux for fun, M$ for $$$...and football season is just a few weeks away!
=============================================================================


Dan Pop

unread,
Jul 14, 1996, 3:00:00 AM7/14/96
to

In <bnelsonD...@netcom.com> bne...@netcom.com (Bob Nelson) writes:

>Kevin D. Quitt (k...@emoryi.jpl.nasa.gov) wrote:
>> On Thu, 11 Jul 1996 10:35:55 -0400, Al Bowers <abo...@combase.com> wrote:
>> >> Dan Pop (Dan...@cern.ch) wrote:
>> >> The key phrase is:
>> >>
>> >> The free function causes the space pointed to by ptr to be
>> >> deallocated, that is, made available for further allocation.
>> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> >Running MS-DOS and Quick-C, I wanted to see if in fact the free function
>> >made available the memory for further allocation.
>
>> It's nice to know that Quick-C is the authoritative source for what is and
>> isn't legal in C. Think of the money I could have saved by not buying all
>> those worthless documents from ANSI/ISO. I could just cry.
>
>IMHO, K&R2 (p. 4) incorrectly give creedence to such thoughts: "In
>cases of doubt, however, the standard and one's own compiler remain

^^^


>the final authorities on the language."

Note the underlined "and". Dunno about others, but I always use my
compiler to test if what I've understood from the C standard is correct.
Whenever the result is not the expected one, it turns out that my
understanding was at fault.

Of course, when the standard says: "this is undefined, unspecified or
implementation-defined", I don't use the compiler to "improve" my
understanding of the language :-)

Bob Nelson

unread,
Jul 15, 1996, 3:00:00 AM7/15/96
to

Dan Pop (Dan...@cern.ch) wrote:
> In <bnelsonD...@netcom.com> bne...@netcom.com (Bob Nelson) writes:
> >Kevin D. Quitt (k...@emoryi.jpl.nasa.gov) wrote:
> >
> >> It's nice to know that Quick-C is the authoritative source for what is and
> >> isn't legal in C. Think of the money I could have saved by not buying all
> >> those worthless documents from ANSI/ISO. I could just cry.
> >
> >IMHO, K&R2 (p. 4) incorrectly give creedence to such thoughts: "In
> >cases of doubt, however, the standard and one's own compiler remain
> ^^^
> >the final authorities on the language."

> Note the underlined "and". Dunno about others, but I always use my
> compiler to test if what I've understood from the C standard is correct.
> Whenever the result is not the expected one, it turns out that my
> understanding was at fault.

In the example you point out of testing, the compiler is used as a
_supplemental_ means toward understanding.

The objection to the phrasing from K&R2 is the slipperly slope
permitting the compiler to share a co-equal status to the Standard by
precisely by the use of the word "and". Barring a fault with one's
understanding (or the code itself), a compiler yielding a result at
odds with the Standard indicates that the compiler is suspect...and,
of course, that the Standard alone shall prevail as the ultimate
authority.

Al Bowers

unread,
Jul 15, 1996, 3:00:00 AM7/15/96
to

Kevin D. Quitt (k...@emoryi.jpl.nasa.gov) or sombody wrote:

> It's nice to know that Quick-C is the authoritative source for what is and
> isn't legal in C. Think of the money I could have saved by not buying all
> those worthless documents from ANSI/ISO. I could just cry.

Striking like a rattlesnake, if the motive of your comment is to brand me a
fool for purchasing Quick C, you are assuming I paid for it. Your venom
missed the mark. Quick C was given to me. If your intention was to tag me
stupid for using Quick C as an ambassador to legal C, your poison got me
throught the boot. However, don't you think that Quick C ( and/or most
compilers) is better suited as an instrument of use (getting work done)
than all those "worthless" ANSI/ISO documents?

Be warned! I am immune to the venom's toxicity. For as you have found out,
I have known for some time, that this ole country boy is por and dum.

Keep striking. Don't stop trying to educate me. One day I wish to be rich.

By the way, if you want to know something about chickens, just ask.

Please! No choking flames or jokes.

Kevin D. Quitt

unread,
Jul 17, 1996, 3:00:00 AM7/17/96
to

On Mon, 15 Jul 1996 10:26:47 -0400, Al Bowers <abo...@combase.com> wrote:

>don't you think that Quick C ( and/or most
>compilers) is better suited as an instrument of use (getting work done)
>than all those "worthless" ANSI/ISO documents?

It's definitely a much better compiler than the ANSI/ISO document that defines
C. The document, on the other hand, *is* slightly more authoritative about
what is and isn't legal C. It is the use of the compiler to test for
compliance that I was remarking on before.

0 new messages