By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,742 Members | 773 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,742 IT Pros & Developers. It's quick & easy.

purge like utility in c

P: n/a
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul

Oct 10 '06 #1
Share this Question
Share on Google+
118 Replies


P: n/a

ra*******************@gmail.com wrote:
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul
well, any use of malloc() without a later free() is going to leak....
But I think it's ttheoretically impossible to figure out what mallocs()
never do a free() without executing all possible paths thru the code
with all possible inputs.

The best way is to write really structured code, something like this:

p = malloc( ... );
dosomethingwith(p);
free( p );

.... and don't have any other paths that can bypass the free().
In practice what's usually done is you write really crappy spaghetti
code, with the free()'s nowhere near the malloc()'s, then use a logging
malloc(), such as www.dmalloc.com gives out, then you run your program,
with luck having it exercise all the possible code paths, then you look
at the list of still-allocated blocks.

The last time I did so, I forgot to free one important struct of
pointers so there were something like 36,337 unfreed pointers using
124,543,000 bytes. Ouch. You should really just write good code in
the first place.

Oct 10 '06 #2

P: n/a
Another way to make your code even safer is to have a strait-jacket
macro or function wrapper which makes it darn near impossible to not
free things, something like:

#define Serious_Wrapper(var,type,size,proc) \
{ type var; var = malloc( size ); proc( var ); free( var ); }
.... but of course this often doesnt fit in well with the flow of your
code. Sigh.

Oct 10 '06 #3

P: n/a
Ancient_Hacker wrote:
Another way to make your code even safer is to have a strait-jacket
macro or function wrapper which makes it darn near impossible to not
free things, something like:

#define Serious_Wrapper(var,type,size,proc) \
{ type var; var = malloc( size ); proc( var ); free( var ); }
... but of course this often doesnt fit in well with the flow of your
code. Sigh.
Oh happy days of BCPL's aptovec.

--
Chris "Essen -9 and counting" Dollin
The shortcuts are all full of people using them.

Oct 10 '06 #4

P: n/a
Ancient_Hacker wrote:
ra*******************@gmail.com wrote:
>>hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul


well, any use of malloc() without a later free() is going to leak....
But I think it's ttheoretically impossible to figure out what mallocs()
never do a free() without executing all possible paths thru the code
with all possible inputs.

The best way is to write really structured code, something like this:

p = malloc( ... );
dosomethingwith(p);
free( p );

... and don't have any other paths that can bypass the free().
A drawback of this advice is that it ties the lifetime of
the dynamic variable to a lexical scope of the code. That is,
it removes most of the reason for having dynamic storage in
the first place; the only advantage over plain `auto' variables
would be the (possibly) less stringent size restrictions.

The chief reason for using dynamic memory is to create
objects whose lifetime is independent of the execution context.
I want to be able to malloc() something in a function, add the
something to a hash table or splay tree or some such, and return
from the function with the something still intact. If I'm not
allowed to do that, there's little point in having malloc().

--
Eric Sosman
es*****@acm-dot-org.invalid
Oct 10 '06 #5

P: n/a
On Tue, 10 Oct 2006 08:00:44 -0400, Eric Sosman wrote:
A drawback of this advice is that it ties the lifetime of
the dynamic variable to a lexical scope of the code.
That's a feature not a drawback!
>That is,
it removes most of the reason for having dynamic storage in
the first place; the only advantage over plain `auto' variables
would be the (possibly) less stringent size restrictions.
.... which really is a huge advantage. Symmetric resource acquisition
and release is the most powerful resource management pattern in C.
The chief reason for using dynamic memory is to create
objects whose lifetime is independent of the execution context.
That's no contradiction to symmetric resource management.
>I want to be able to malloc() something in a function, add the
something to a hash table or splay tree or some such, and return
from the function with the something still intact. If I'm not
allowed to do that, there's little point in having malloc().
If you feel the need to return a dynamically allocated object just
allocate it one scope higher and pass it to the function thereby
preserving symmetry of de-/allocation. BTW, the Standard C library
doesn't allocate objects that have to be freed by the caller.

Best regards,
Roland Pibinger
Oct 10 '06 #6

P: n/a
In article <45*************@news.utanet.at>,
Roland Pibinger <rp*****@yahoo.comwrote:
>BTW, the Standard C library
doesn't allocate objects that have to be freed by the caller.
malloc() does...

-- Richard
Oct 10 '06 #7

P: n/a
Roland Pibinger wrote:
If you feel the need to return a dynamically allocated object just
allocate it one scope higher and pass it to the function thereby
preserving symmetry of de-/allocation.
Not obviously possible in general. For example, a parser that delivers
an abstract syntax tree: you don't know what to allocate until you
come to allocate it.

(Also, detaching allocation from initialisation is an open invitation
to misuse the consequent mutability of the tree objects.)

--
Chris "Essen -9 and counting" Dollin
The shortcuts are all full of people using them.

Oct 10 '06 #8

P: n/a
ra*******************@gmail.com wrote:
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul

Stop messing with malloc/free and use a garbage collector.
The machine will do the hard work, you do the driving.

jacob
Oct 10 '06 #9

P: n/a
jacob navia wrote:
ra*******************@gmail.com wrote:
>hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul
Stop messing with malloc/free and use a garbage collector.
The machine will do the hard work, you do the driving.
Be aware that if you do so you are leaving Standard C. That
may be a reasonable choice for generic-you, or it may not.
Make sure generic-you understand the consequences.

If one is prepared to give up C standardness for garbage collection,
there are other languages Out There that come with GC as standard.
Some of them are even designed for it.

--
Chris "Essen -9 and counting" Dollin
"No-one here is exactly what he appears." G'kar, /Babylon 5/

Oct 10 '06 #10

P: n/a
jacob navia said:

<snip>
Stop messing with malloc/free and use a garbage collector.
C doesn't have one, as you either know or ought to know. Stop trolling.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #11

P: n/a
Chris Dollin wrote:
jacob navia wrote:

>>ra*******************@gmail.com wrote:
>>>hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul

Stop messing with malloc/free and use a garbage collector.
The machine will do the hard work, you do the driving.


Be aware that if you do so you are leaving Standard C. That
may be a reasonable choice for generic-you, or it may not.
Make sure generic-you understand the consequences.

If one is prepared to give up C standardness for garbage collection,
there are other languages Out There that come with GC as standard.
Some of them are even designed for it.
C was designed with a GC in mind.

That is why the provided standard functions are so error-prone
and full of hazards for the unwary. Because you are supposed to
use the GC obviously!

:-)

Besides, all other languages do not provide with the efficiency
of C. Coupled with a good GC, the need for destructors, and
all the associated machinery disappears. You obtain a simpler,
easier to use language, without the problems of other "OO"
stuff.

jacob
Oct 10 '06 #12

P: n/a
ra*******************@gmail.com said:
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them....
It is not possible to write a program that will point out all possible leaks
in any arbitrary program, with no false positives; to do so would be
equivalent to solving the Halting Problem.

It is, however, trivial to set up a system which detects and reports actual
leaks. I wrote one myself, for my own use, so it can't be that hard, can
it? But of course there is always valgrind...

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #13

P: n/a
Richard Heathfield wrote:
jacob navia said:

<snip>
>>Stop messing with malloc/free and use a garbage collector.


C doesn't have one, as you either know or ought to know. Stop trolling.
What "C"?

Yours?

The garbage collector can be used as an external library.
If you do not recommend its use, or somehow are GC impaired
that is YOUR opinion.

Mine is that many people are wasting a lot of time
chasing bugs related to malloc/free instead of programming
their application.
They should use a GC and be done with it.

jacob
Oct 10 '06 #14

P: n/a
Richard Heathfield wrote:
ra*******************@gmail.com said:

>>hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them....


It is not possible to write a program that will point out all possible leaks
in any arbitrary program, with no false positives; to do so would be
equivalent to solving the Halting Problem.

It is, however, trivial to set up a system which detects and reports actual
leaks. I wrote one myself, for my own use, so it can't be that hard, can
it? But of course there is always valgrind...
Interesting. You recommend valgrind, but you are against a Garbage
Collector.

Does "C" has a "valgrind"????

No, I do not find that word in my copy of the C standard. But that is OK
of course. You can recommend valgrind, but when I recommend a garbage
collector the hell rains over me and I am flamed of being "a troll".

Gosh Heathfield, just stop that ok?

You ARE entitled to your opinion and if you find valgrind OK it IS OK
to recommend it to anyone. But when I recommend a GC, please stop
treating me of "troll" or saying the "C doesn't have a GC".

OK?

Thanks

Oct 10 '06 #15

P: n/a
jacob navia <ja***@jacob.remcomp.frwrote:
Richard Heathfield wrote:
jacob navia said:
>Stop messing with malloc/free and use a garbage collector.
C doesn't have one, as you either know or ought to know. Stop trolling.

What "C"?

Yours?
_The_ C. The one defined by the International Organisation for
Standards. Which, last time I looked, France was a signatory to, as
well.
They should use a GC and be done with it.
If "they" want pain, inefficiency, and leaky programs, yes.

Richard
Oct 10 '06 #16

P: n/a
Richard Bos wrote:
jacob navia <ja***@jacob.remcomp.frwrote:

>>Richard Heathfield wrote:
>>>jacob navia said:
Stop messing with malloc/free and use a garbage collector.

C doesn't have one, as you either know or ought to know. Stop trolling.

What "C"?

Yours?


_The_ C. The one defined by the International Organisation for
Standards. Which, last time I looked, France was a signatory to, as
well.

>>They should use a GC and be done with it.


If "they" want pain, inefficiency, and leaky programs, yes.

Richard
Pain?

Look, seeing the pain in the... of malloc/free, the problems of a GC
are nothing at all.

Inefficiency? And when you malloc something you think that malloc
doesn't do a GC to compact memory? malloc is not free, it can be
vary expensive.

jacob
Oct 10 '06 #17

P: n/a
On Tue, 10 Oct 2006 14:19:12 +0000, Roland Pibinger wrote:
On Tue, 10 Oct 2006 08:00:44 -0400, Eric Sosman wrote:
>>That is,
it removes most of the reason for having dynamic storage in
the first place; the only advantage over plain `auto' variables
would be the (possibly) less stringent size restrictions.

... which really is a huge advantage. Symmetric resource acquisition
and release is the most powerful resource management pattern in C.
Define "most powerful". It's certainly not the most useful in many cases.
And for many "types" pre-allocating is very much not the safest option
(like string types). It also strongly ties the caller to the callee
implicitly, which you often don't want from a design/quality POV.
>>I want to be able to malloc() something in a function, add the something
to a hash table or splay tree or some such, and return from the function
with the something still intact. If I'm not allowed to do that, there's
little point in having malloc().

If you feel the need to return a dynamically allocated object just
allocate it one scope higher and pass it to the function thereby
preserving symmetry of de-/allocation.
Again, this implies that the callee knows what the caller is allocating
and still the lifetime may extend well beyond the call. For instance a
network connection to an event based daemon wouldn't want the event
handling code to know about the full objects being allocated, and it would
need to remain over CONNECT/READ/WRITE/SHUTDOWN events. Which could be
many trips through the main loop.
BTW, the Standard C library
doesn't allocate objects that have to be freed by the caller.
Well apart from *alloc, there are at least two in the Std. library: fopen
and tmpfile. Both due to not wanting the callee to have to know intimately
about the object created. If you then get out of the theoretical there
are many more examples like: asprintf, acl_get_file and opendir.

--
James Antill -- ja***@and.org
http://www.and.org/and-httpd

Oct 10 '06 #18

P: n/a
On Tue, 10 Oct 2006 15:32:40 +0100, Chris Dollin wrote:
>Roland Pibinger wrote:
>If you feel the need to return a dynamically allocated object just
allocate it one scope higher and pass it to the function thereby
preserving symmetry of de-/allocation.

Not obviously possible in general.
Not possible in general but in so many cases that I'd call it _the_ C
resource management idiom (pattern).
>For example, a parser that delivers
an abstract syntax tree: you don't know what to allocate until you
come to allocate it.
That's not a contradiction to the quest for symmetry of allocation and
deallocation as long as the scope of both is the same.

Best wishes,
Roland Pibinger
Oct 10 '06 #19

P: n/a
jacob navia said:

<snip>
C was designed with a GC in mind.
Can you support this claim?
That is why the provided standard functions are so error-prone
and full of hazards for the unwary. Because you are supposed to
use the GC obviously!
No, programmers are supposed to be wary.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #20

P: n/a
jacob navia said:
Richard Heathfield wrote:
>jacob navia said:

<snip>
>>>Stop messing with malloc/free and use a garbage collector.


C doesn't have one, as you either know or ought to know. Stop trolling.

What "C"?
(a) The language defined by "The C Programming Language", 1st edition
(b) The language defined by ISO/IEC 9899:1990
(c) The language defined by ISO/IEC 9899:1999

All of these languages, and no others, have a reasonable claim to be called
"C". None of them incorporates a garbage collector.
The garbage collector can be used as an external library.
Third-party libraries are not topical here.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #21

P: n/a
jacob navia said:
Richard Heathfield wrote:
>But of course there is always valgrind...

Interesting. You recommend valgrind,
No, I just mentioned it, that's all. I don't recommend it (and neither do I
recommend against it). How can I? I've never needed to use it. But I am
told by its users that it's very helpful to them.
but you are against a Garbage Collector.
My understanding of valgrind is that you can use it without modifying your C
source code, so the program remains uncorrupted by the tool. And, having
used it to identify and remove any leaks from your program, the program
remains portable, and can still work independently of valgrind, so
portability is not affected.

Is my understanding of valgrind incorrect? Or, if I've got it about right,
can you claim the same characteristics for your garbage collector? That is,
can it work without the C source having to call any of its routines, and
will the program still work correctly without leaking memory even when that
program is moved to a platform where the garbage collector is unavailable?
If so, then I remove my objections. Otherwise, I don't.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #22

P: n/a
jacob navia said:

<snip>
Look, seeing the pain in the... of malloc/free,
Of all the things in C that can cause pain, this is one of the most trivial.
It is fairly easy not to leak memory, and remarkably easy to detect memory
leaks. If you can't do it, fine, but that's your problem, nobody else's.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #23

P: n/a
In article <45***********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>C was designed with a GC in mind.
Dennis Ritchie documented otherwise:

http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

Off-stack, dynamically-allocated storage is provided only by a
library routine and the burden of managing it is placed on the
programmer: C is hostile to automatic garbage collection.
--
All is vanity. -- Ecclesiastes
Oct 10 '06 #24

P: n/a
Walter Roberson said:
In article <45***********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>>C was designed with a GC in mind.

Dennis Ritchie documented otherwise
And what would /he/ know about it? :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #25

P: n/a
Richard Heathfield posted:
>The garbage collector can be used as an external library.

Third-party libraries are not topical here.

I suppose the most basic form would be something like:

#include <stddef.h>
#include <stdlib.h>

typedef struct AllocLink {
void *p;
struct AllocLink *p_prev;
} AllocLink;

AllocLink first_link = {0,0};
AllocLink *plink = &first_link;

void *mallocGC(size_t const len)
{
void freeGC(void);

static int first_time = 1;
AllocLink *const p_new_link = malloc(sizeof *p_new_link);

if (!p_new_link) return 0;

p_new_link->p = malloc(len);

if(!p_new_link->p) { free(p_new_link); return 0; }

p_new_link->p_prev = plink;

plink = p_new_link;

if(first_time) first_time = 0, atexit(freeGC);

return plink->p;
}

void freeGC(void)
{
AllocLink *p_prev;

do
{
free(plink->p);
p_prev = plink->p_prev;
free(plink);
plink = p_prev;
} while(plink->p);
}
The behaviour would be undefined if you were to use "free" to deallocate
memory allocated by "mallocGC".

--

Frederick Gotham
Oct 10 '06 #26

P: n/a
jacob navia wrote:
Richard Heathfield wrote:
>ra*******************@gmail.com said:

>>hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them....


It is not possible to write a program that will point out all possible
leaks in any arbitrary program, with no false positives; to do so
would be equivalent to solving the Halting Problem.

It is, however, trivial to set up a system which detects and reports
actual leaks. I wrote one myself, for my own use, so it can't be that
hard, can it? But of course there is always valgrind...

Interesting. You recommend valgrind, but you are against a Garbage
Collector.

Does "C" has a "valgrind"????

No, I do not find that word in my copy of the C standard. But that is OK
of course. You can recommend valgrind, but when I recommend a garbage
collector the hell rains over me and I am flamed of being "a troll".
<snip>

Stop talking complete rubbish. As you well know valgrind can be used
with any standard C program where as garbage collection cannot.
--
Flash Gordon
Oct 10 '06 #27

P: n/a
jacob navia wrote:
Chris Dollin wrote:
>Be aware that if you do so you are leaving Standard C. That
may be a reasonable choice for generic-you, or it may not.
Make sure generic-you understand the consequences.

If one is prepared to give up C standardness for garbage collection,
there are other languages Out There that come with GC as standard.
Some of them are even designed for it.

C was designed with a GC in mind.
How can a GC decide whether a value in memory is actually a pointer or not?

static intptr_t b;

{
char *a = malloc(1000);
b = (intptr_t)a ^ 0xDEADBEEF;
a = NULL;
some_long_procedure();
a = (char*) (b ^ 0xDEADBEEF);
do_something_with(a);
}

During the execution of some_long_procedure() there is no memory
containing the address of the allocated block. The pointer has been
safely stashed in an integer and obfuscated by XORing it. What if the GC
goes ahead and collects the memory, and it's no longer available later?

What about this:

{
char *a = malloc(1000);
FILE *fp = fopen("tmp", "wb");
fwrite(&a, sizeof a, 1, fp);
fclose(fp);
a = NULL;

some_long_procedure();

fp = fopen("tmp", "rb");
fread(&a, sizeof a, 1, fp);
fclose(fp);

do_something_with(a);
}

--
Simon.
Oct 10 '06 #28

P: n/a
Flash Gordon wrote:
jacob navia wrote:
>Richard Heathfield wrote:
>>ra*******************@gmail.com said:
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them....

It is not possible to write a program that will point out all
possible leaks in any arbitrary program, with no false positives; to
do so would be equivalent to solving the Halting Problem.

It is, however, trivial to set up a system which detects and reports
actual leaks. I wrote one myself, for my own use, so it can't be that
hard, can it? But of course there is always valgrind...

Interesting. You recommend valgrind, but you are against a Garbage
Collector.

Does "C" has a "valgrind"????

No, I do not find that word in my copy of the C standard. But that is OK
of course. You can recommend valgrind, but when I recommend a garbage
collector the hell rains over me and I am flamed of being "a troll".


<snip>

Stop talking complete rubbish. As you well know valgrind can be used
with any standard C program where as garbage collection cannot.
Who is talking complete rubbish?

Here is a list of limitations of valgrind:
Valgrind will run Linux ELF binaries, on a kernel 2.4.X or 2.6.X system,
on the x86, amd64, ppc32 and ppc64 architectures, subject to the
following constraints:

*

On x86 and amd64, there is no support for 3DNow! instructions. If
the translator encounters these, Valgrind will generate a SIGILL when
the instruction is executed. Apart from that, on x86 and amd64,
essentially all instructions are supported, up to and including SSE2.
Version 3.1.0 includes limited support for SSE3 on x86. This could be
improved if necessary.

On ppc32 and ppc64, almost all integer, floating point and
Altivec instructions are supported. Specifically: integer and FP insns
that are mandatory for PowerPC, the "General-purpose optional" group
(fsqrt, fsqrts, stfiwx), the "Graphics optional" group (fre, fres,
frsqrte, frsqrtes), and the Altivec (also known as VMX) SIMD instruction
set, are supported.
*

Atomic instruction sequences are not properly supported, in the
sense that their atomicity is not preserved. This will affect any use of
synchronization via memory shared between processes. They will appear to
work, but fail sporadically.
*

If your program does its own memory management, rather than using
malloc/new/free/delete, it should still work, but Valgrind's error
checking won't be so effective. If you describe your program's memory
management scheme using "client requests" (see The Client Request
mechanism), Memcheck can do better. Nevertheless, using malloc/new and
free/delete is still the best approach.
*

Valgrind's signal simulation is not as robust as it could be.
Basic POSIX-compliant sigaction and sigprocmask functionality is
supplied, but it's conceivable that things could go badly awry if you do
weird things with signals. Workaround: don't. Programs that do non-POSIX
signal tricks are in any case inherently unportable, so should be
avoided if possible.
*

Machine instructions, and system calls, have been implemented on
demand. So it's possible, although unlikely, that a program will fall
over with a message to that effect. If this happens, please report ALL
the details printed out, so we can try and implement the missing feature.
*

Memory consumption of your program is majorly increased whilst
running under Valgrind. This is due to the large amount of
administrative information maintained behind the scenes. Another cause
is that Valgrind dynamically translates the original executable.
Translated, instrumented code is 12-18 times larger than the original so
you can easily end up with 50+ MB of translations when running (eg) a
web browser.
*

Valgrind can handle dynamically-generated code just fine. If you
regenerate code over the top of old code (ie. at the same memory
addresses), if the code is on the stack Valgrind will realise the code
has changed, and work correctly. This is necessary to handle the
trampolines GCC uses to implemented nested functions. If you regenerate
code somewhere other than the stack, you will need to use the
--smc-check=all flag, and Valgrind will run more slowly than normal.
*

As of version 3.0.0, Valgrind has the following limitations in
its implementation of x86/AMD64 floating point relative to IEEE754.

Precision: There is no support for 80 bit arithmetic. Internally,
Valgrind represents all such "long double" numbers in 64 bits, and so
there may be some differences in results. Whether or not this is
critical remains to be seen. Note, the x86/amd64 fldt/fstpt instructions
(read/write 80-bit numbers) are correctly simulated, using conversions
to/from 64 bits, so that in-memory images of 80-bit numbers look correct
if anyone wants to see.

The impression observed from many FP regression tests is that the
accuracy differences aren't significant. Generally speaking, if a
program relies on 80-bit precision, there may be difficulties porting it
to non x86/amd64 platforms which only support 64-bit FP precision. Even
on x86/amd64, the program may get different results depending on whether
it is compiled to use SSE2 instructions (64-bits only), or x87
instructions (80-bit). The net effect is to make FP programs behave as
if they had been run on a machine with 64-bit IEEE floats, for example
PowerPC. On amd64 FP arithmetic is done by default on SSE2, so amd64
looks more like PowerPC than x86 from an FP perspective, and there are
far fewer noticable accuracy differences than with x86.

Rounding: Valgrind does observe the 4 IEEE-mandated rounding
modes (to nearest, to +infinity, to -infinity, to zero) for the
following conversions: float to integer, integer to float where there is
a possibility of loss of precision, and float-to-float rounding. For all
other FP operations, only the IEEE default mode (round to nearest) is
supported.

Numeric exceptions in FP code: IEEE754 defines five types of
numeric exception that can happen: invalid operation (sqrt of negative
number, etc), division by zero, overflow, underflow, inexact (loss of
precision).

For each exception, two courses of action are defined by 754:
either (1) a user-defined exception handler may be called, or (2) a
default action is defined, which "fixes things up" and allows the
computation to proceed without throwing an exception.

Currently Valgrind only supports the default fixup actions.
Again, feedback on the importance of exception support would be appreciated.

When Valgrind detects that the program is trying to exceed any of
these limitations (setting exception handlers, rounding mode, or
precision control), it can print a message giving a traceback of where
this has happened, and continue execution. This behaviour used to be the
default, but the messages are annoying and so showing them is now
optional. Use --show-emwarns=yes to see them.

The above limitations define precisely the IEEE754 'default'
behaviour: default fixup on all exceptions, round-to-nearest operations,
and 64-bit precision.
*

As of version 3.0.0, Valgrind has the following limitations in
its implementation of x86/AMD64 SSE2 FP arithmetic, relative to IEEE754.

Essentially the same: no exceptions, and limited observance of
rounding mode. Also, SSE2 has control bits which make it treat
denormalised numbers as zero (DAZ) and a related action, flush denormals
to zero (FTZ). Both of these cause SSE2 arithmetic to be less accurate
than IEEE requires. Valgrind detects, ignores, and can warn about,
attempts to enable either mode.
*

As of version 3.2.0, Valgrind has the following limitations in
its implementation of PPC32 and PPC64 floating point arithmetic,
relative to IEEE754.

Scalar (non-Altivec): Valgrind provides a bit-exact emulation of
all floating point instructions, except for "fre" and "fres", which are
done more precisely than required by the PowerPC architecture
specification. All floating point operations observe the current
rounding mode.

However, fpscr[FPRF] is not set after each operation. That could
be done but would give measurable performance overheads, and so far no
need for it has been found.

As on x86/AMD64, IEEE754 exceptions are not supported: all
floating point exceptions are handled using the default IEEE fixup
actions. Valgrind detects, ignores, and can warn about, attempts to
unmask the 5 IEEE FP exception kinds by writing to the floating-point
status and control register (fpscr).

Vector (Altivec, VMX): essentially as with x86/AMD64 SSE/SSE2: no
exceptions, and limited observance of rounding mode. For Altivec, FP
arithmetic is done in IEEE/Java mode, which is more accurate than the
Linux default setting. "More accurate" means that denormals are handled
properly, rather than simply being flushed to zero.

Programs which are known not to work are:

emacs starts up but immediately concludes it is out of memory and
aborts. It may be that Memcheck does not provide a good enough emulation
of the mallinfo function. Emacs works fine if you build it to use the
standard malloc/free routines.
Oct 10 '06 #29

P: n/a
Richard Heathfield wrote:
jacob navia said:

>>Richard Heathfield wrote:
>>>But of course there is always valgrind...

Interesting. You recommend valgrind,


No, I just mentioned it, that's all. I don't recommend it (and neither do I
recommend against it). How can I? I've never needed to use it. But I am
told by its users that it's very helpful to them.

>>but you are against a Garbage Collector.


My understanding of valgrind is that you can use it without modifying your C
source code, so the program remains uncorrupted by the tool. And, having
used it to identify and remove any leaks from your program, the program
remains portable, and can still work independently of valgrind, so
portability is not affected.

Is my understanding of valgrind incorrect? Or, if I've got it about right,
can you claim the same characteristics for your garbage collector? That is,
can it work without the C source having to call any of its routines, and
will the program still work correctly without leaking memory even when that
program is moved to a platform where the garbage collector is unavailable?
If so, then I remove my objections. Otherwise, I don't.

You do:
#define malloc(a) GC_malloc(a)
#define free(a)

And that is it.
Most programs will work like this, unless (of course) they write
pointers to a file, or put their pointers in e-mail messages, or
whatever.

We have discussed this several times.

By the way, the limitations of valgrind are FAR more long. See my reply
to "Flash Gordon"...
Oct 10 '06 #30

P: n/a
On Tue, 10 Oct 2006 13:13:21 -0400, James Antill wrote:
>On Tue, 10 Oct 2006 14:19:12 +0000, Roland Pibinger wrote:
>Symmetric resource acquisition
and release is the most powerful resource management pattern in C.

Define "most powerful". It's certainly not the most useful in many cases.
And the better idiom for resource management is?
>And for many "types" pre-allocating is very much not the safest option
(like string types).
pre-allocating? It's merely about the symmetry of allocation and
deallocation (eg. malloc/free) in one scope.
>It also strongly ties the caller to the callee
implicitly, which you often don't want from a design/quality POV.
The ties are explicit and the responsibilities are clear: Whoever
allocates a resource has to deallocate/release it in the same scope.
> BTW, the Standard C library
doesn't allocate objects that have to be freed by the caller.

Well apart from *alloc, there are at least two in the Std. library: fopen
and tmpfile. Both due to not wanting the callee to have to know intimately
about the object created. If you then get out of the theoretical there
are many more examples like: asprintf, acl_get_file and opendir.
The point is that you allocate a resource (with malloc, fopen,
opendir, ...) which you symmetrically deallocate/release (with free,
fclose, closedir, ...).

Best regards,
Roland Pibinger
Oct 10 '06 #31

P: n/a
jacob navia said:
Flash Gordon wrote:
>>
<snip>
>>
Stop talking complete rubbish. As you well know valgrind can be used
with any standard C program where as garbage collection cannot.

Who is talking complete rubbish?

Here is a list of limitations of valgrind:
....none of which is relevant to the fact that valgrind is an external
utility, like gdb or time or gprof or cat or type. It isn't part of the
program. You don't render your program non-portable by using it. Unlike
your garbage collection thing.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #32

P: n/a
jacob navia said:

<snip>
>
You do:
#define malloc(a) GC_malloc(a)
#define free(a)

And that is it.
foo.c:117: warning: implicit declaration of function `GC_malloc'
foo.c:117: warning: initialization makes pointer from integer without a cas
foo.c:117: undefined reference to `GC_malloc'
collect2: ld returned 1 exit status
make: *** [foo] Error 1

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #33

P: n/a
jacob navia posted:
#define malloc(a) GC_malloc(a)

Two caveats:

int main(void)
{
void *(*p)(size_t) = malloc;

(malloc)(56);

return 0;
}
--

Frederick Gotham
Oct 10 '06 #34

P: n/a
Richard Heathfield wrote:
jacob navia said:

<snip>
>>You do:
#define malloc(a) GC_malloc(a)
#define free(a)

And that is it.


foo.c:117: warning: implicit declaration of function `GC_malloc'
foo.c:117: warning: initialization makes pointer from integer without a cas
foo.c:117: undefined reference to `GC_malloc'
collect2: ld returned 1 exit status
make: *** [foo] Error 1
Yes, do not use GC_malloc. You see?
It doesn't work.
Stay with "free" and "malloc" Heathfield. GC_malloc is too much for you.
Oct 10 '06 #35

P: n/a
Richard Heathfield wrote:
jacob navia said:

>>Flash Gordon wrote:
<snip>
>>>Stop talking complete rubbish. As you well know valgrind can be used
with any standard C program where as garbage collection cannot.

Who is talking complete rubbish?

Here is a list of limitations of valgrind:


...none of which is relevant to the fact that valgrind is an external
utility, like gdb or time or gprof or cat or type. It isn't part of the
program. You don't render your program non-portable by using it. Unlike
your garbage collection thing.

<snip>
Boehm's GC runs under linux, windows, hp unices, and *many* OS.

But I do not want that YOU use a GC Heathfield, since it is
too much for you. Stay with your malloc/free.

Besides, if you use the GC you will not be able to run in the embedded
OS in your toaster.

WHO CARES?
Oct 10 '06 #36

P: n/a
Frederick Gotham wrote:
Richard Heathfield posted:

>>>The garbage collector can be used as an external library.

Third-party libraries are not topical here.

I suppose the most basic form would be something like:

#include <stddef.h>
#include <stdlib.h>

typedef struct AllocLink {
void *p;
struct AllocLink *p_prev;
} AllocLink;

AllocLink first_link = {0,0};
AllocLink *plink = &first_link;

void *mallocGC(size_t const len)
{
void freeGC(void);

static int first_time = 1;
AllocLink *const p_new_link = malloc(sizeof *p_new_link);

if (!p_new_link) return 0;

p_new_link->p = malloc(len);

if(!p_new_link->p) { free(p_new_link); return 0; }

p_new_link->p_prev = plink;

plink = p_new_link;

if(first_time) first_time = 0, atexit(freeGC);

return plink->p;
}

void freeGC(void)
{
AllocLink *p_prev;

do
{
free(plink->p);
p_prev = plink->p_prev;
free(plink);
plink = p_prev;
} while(plink->p);
}
The behaviour would be undefined if you were to use "free" to deallocate
memory allocated by "mallocGC".
Maybe. Better do not use it.

Use malloc/free and do everything manually with all the associated bugs.

I was recommending the GC for other people that like caring about their
programs, their algorithms, their deadlines, instead of chasing
malloc/free bugs!!!

You like malloc/free?

OK. I do not earn any percentages in GC sales!
Oct 10 '06 #37

P: n/a
Richard Heathfield wrote:
jacob navia said:

<snip>

>>Look, seeing the pain in the... of malloc/free,


Of all the things in C that can cause pain, this is one of the most trivial.
It is fairly easy not to leak memory, and remarkably easy to detect memory
leaks. If you can't do it, fine, but that's your problem, nobody else's.
Incredible.

There is a whole INDUSTRY of software for chasing
malloc/free bugs. Huge software systems like valgrind,
purify, etc etc are built JUST TO CHASE THOSE BUGS.

Incredible, it is SO EASY to avoid any problems and
there are SO MANY people trying to fix that!!!

They are all stupid, like me... They did not see what
Heathfield sees... Damm it!

Oct 10 '06 #38

P: n/a
jacob navia said:
Richard Heathfield wrote:
>jacob navia said:

<snip>
>>>You do:
#define malloc(a) GC_malloc(a)
#define free(a)

And that is it.


foo.c:117: warning: implicit declaration of function `GC_malloc'
foo.c:117: warning: initialization makes pointer from integer without a
cas foo.c:117: undefined reference to `GC_malloc'
collect2: ld returned 1 exit status
make: *** [foo] Error 1

Yes, do not use GC_malloc. You see?
It doesn't work.
Precisely so.
Stay with "free" and "malloc" Heathfield. GC_malloc is too much for you.
On the contrary, it's not enough.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #39

P: n/a
jacob navia said:

<snip>
Boehm's GC runs under linux, windows, hp unices, and *many* OS.
That's funny. I tried it under Linux and it didn't even exist, let alone
run.

<snip>
WHO CARES?
You don't, obviously. But comp.lang.c is for discussions about C, not
discussions about stuff that isn't C.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #40

P: n/a
jacob navia said:

<snip>
>
Maybe. Better do not use [garbage collection].
Excellent advice.
Use malloc/free and do everything manually with all the associated bugs.
I'm happy to use malloc/free, but I see no need to include the bugs.
I was recommending the GC for other people that like caring about their
programs, their algorithms, their deadlines, instead of chasing
malloc/free bugs!!!
The claim "Jacob Navia can't use malloc/free without riddling his programs
with bugs" is a reasonable one, and if that's what you're claiming, I take
your word for it. But the claim "nobody else can either" is ridiculous.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #41

P: n/a
jacob navia said:

<snip>
There is a whole INDUSTRY of software for chasing
malloc/free bugs. Huge software systems like valgrind,
purify, etc etc are built JUST TO CHASE THOSE BUGS.
Yeah. That's one reason they're so easy to find and fix. Duh.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 10 '06 #42

P: n/a
jacob navia wrote:
Besides, all other languages do not provide with the efficiency
of C. Coupled with a good GC, the need for destructors, and
all the associated machinery disappears. You obtain a simpler,
easier to use language, without the problems of other "OO"
stuff.
does your garbage collection close files for me too?

Oct 10 '06 #43

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
Richard Heathfield wrote:
>jacob navia said:
>>>Richard Heathfield wrote:

But of course there is always valgrind...

Interesting. You recommend valgrind,
No, I just mentioned it, that's all. I don't recommend it (and
neither do I recommend against it). How can I? I've never needed to
use it. But I am told by its users that it's very helpful to them.
>>>but you are against a Garbage Collector.
My understanding of valgrind is that you can use it without
modifying your C source code, so the program remains uncorrupted by
the tool. And, having used it to identify and remove any leaks from
your program, the program remains portable, and can still work
independently of valgrind, so portability is not affected.
Is my understanding of valgrind incorrect? Or, if I've got it about
right, can you claim the same characteristics for your garbage
collector? That is, can it work without the C source having to call
any of its routines, and will the program still work correctly
without leaking memory even when that program is moved to a platform
where the garbage collector is unavailable? If so, then I remove my
objections. Otherwise, I don't.

You do:
#define malloc(a) GC_malloc(a)
#define free(a)

And that is it.
No, that is not it.

In addition to your two #defines, you need to tell the linker where to
find the GC_malloc() function. And if you don't add a #include for
whatever header contains the declaration of GC_malloc, you'll invoke
undefined behavior every time you call it, just like calling malloc()
without a "#include stdlib.h>". This will be a real problem on
systems with 32-bit int and 64 bit pointers, for example.

I wonder what else you've left out.
Most programs will work like this, unless (of course) they write
pointers to a file, or put their pointers in e-mail messages, or
whatever.

We have discussed this several times.
And every time it comes up, you advocate GC, but somebody else has to
mention the limitations. Garbage collection may be the greatest thing
since sliced bread, but nobody should try to use it without
understanding the caveats.

Garbage collection can work only if all pointer values in the program
are visible to the garbage collector at all times. That's probably
already the case for most programs, but ignoring the issue is
dangerous.
By the way, the limitations of valgrind are FAR more long. See my reply
to "Flash Gordon"...
I looked over it very briefly. It only works on a limited set of
platforms; that's ok if your code is portable and you have access to
such a system. (Yes, that's a real limitation that you should be
aware of.) Most of the other limitations seemed to apply only to code
that uses system-specific features. And all this was in response to a
brief *mention* of valgrind by Richard Heathfield. (I've never used
it myself, so I can't really comment further.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 10 '06 #44

P: n/a
Fellas! Come On!

Senator Ted Stevens has caught on! We're clogging up the Internet
pipes with all these long discussions!

I suggest we get the feds off our backs by coming up with a set of
well-known abbreviations, denoted by letters, thereby shortening these
interminable postings, something like:

A: I am wonderful, all-knowing, and generally infallible.
B: Use a garbage collector.
C: It's not C.
D: It's not K&R C.
E: you misdeclared main()
F: Use my wonderful C compiler, only slightly buggy.
G: Oh if only C had feature X of language Y!
H: Please fix my program below, it has an obscure problem.
I: Oh yes you can.
J: Oh no you can't.
K: I blow my nose in your general direction.

.... rest to be assigned as needed.

thereby all the stuff clogging the pipes can be reduced to a short
series of capital letters.
For even more brevity, we can just assume each posting ends with "K"
unless otherwise noted.

Oct 10 '06 #45

P: n/a
ra*******************@gmail.com wrote:
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.... i am trying to come
with something like this but do not know where to start...

any help on where to begin would be highly appriciated
kind regards
rahul

For each call to malloc you should have a call to free to let go of
that mem segment. A simplistic way of tracing any potential leaks is
discribed by Franek in his book: Memory as a Programming Concept in C
and C+, using the preprocessor:

#define malloc(size) debug_malloc(__FILE__,__LINE__,size)
#define free(ptr) debug_free(__FILE__,__LINE__,ptr)

protoypes:

void debug_malloc(const char *src,int line, size_t size)
void debug_free(const cahr *src,int line, void* ptr)

then simply link it to the definitions of these in your program and you
can have a handy reference of what was allocated and what was freed.
Good book and will help you think how you could fully implement your
question. I tried it out, but it can get a bit hairy as your code
becomes more complex...nice place to start though.

Oct 10 '06 #46

P: n/a
Richard Heathfield <in*****@invalid.invalidwrites:
jacob navia said:
<snip>
>>
Maybe. Better do not use [garbage collection].

Excellent advice.
>Use malloc/free and do everything manually with all the associated bugs.

I'm happy to use malloc/free, but I see no need to include the bugs.
>I was recommending the GC for other people that like caring about their
programs, their algorithms, their deadlines, instead of chasing
malloc/free bugs!!!

The claim "Jacob Navia can't use malloc/free without riddling his programs
with bugs" is a reasonable one, and if that's what you're claiming, I take
your word for it. But the claim "nobody else can either" is ridiculous.
Garbage collection in C may or may not be a good solution for some
problems in some circumstances. The fact that its major advocate in
this newsgroup chooses to insult anyone who points out any potential
flaws shouldn't prevent anyone from looking into it. Ignoring jacob
navia needn't imply ignoring GC.

Of course, if you choose not to use GC, that's ok too; I make no
recommendation one way or the other.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 10 '06 #47

P: n/a
ra*******************@gmail.com wrote:
hi .. can we design a program in c which will point out the possible
memory leaks in any given c file and fix them.
http://en.wikipedia.org/wiki/Memory_debugger
Oct 10 '06 #48

P: n/a
Ancient_Hacker wrote:
well, any use of malloc() without a later free() is going to leak....
But I think it's ttheoretically impossible to figure out what mallocs()
never do a free() without executing all possible paths thru the code
with all possible inputs.
Halting Problem, proven undecidable.
Oct 10 '06 #49

P: n/a
In article <Lr******************************@bt.com>,
Richard Heathfield <in*****@invalid.invalidwrote:
>My understanding of valgrind is that you can use it without modifying your C
source code, so the program remains uncorrupted by the tool.
There are garbage collectors for C with that property. You just link
with a different version of malloc() and free(), where typically the
latter is a no-op.
>And, having
used it to identify and remove any leaks from your program, the program
remains portable, and can still work independently of valgrind, so
portability is not affected.
Is a program that never calls free() portable? It just sees different
implementation limits from one which does.
>will the program still work correctly without leaking memory even when that
program is moved to a platform where the garbage collector is unavailable?
A conforming C implementation is not required not to leak memory, is it?

Seriously, a conservative garbage collector is a reasonable approach
if your program fits certain common constraints and your portability
requirements match the collector in question. Much the same as deciding
to rely on a non-standard library, really.

-- Richard
Oct 10 '06 #50

118 Replies

This discussion thread is closed

Replies have been disabled for this discussion.