Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   safe to fclose stdout to avoid memory leak? (http://www.velocityreviews.com/forums/t530857-safe-to-fclose-stdout-to-avoid-memory-leak.html)

Pietro Cerutti 08-20-2007 03:35 PM

safe to fclose stdout to avoid memory leak?
 
Hi group,
I just noticed that a malloc w/out relative free occurs in the standard
C library (or at least, on my implementation of it).

> cat test.c

#include <stdio.h>
int main(void) {
printf("%s\n", "Hello");
return (0);
}

> gcc -o test test.c
> valgrind --leak-check=yes --show-reachable=yes -v ./test

[snip bla bla]
4096 bytes in 1 blocks are still reachable in loss record 1 of 1
at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
by 0x3C116E77: __swsetup (in /lib/libc.so.6)
by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)

Now, if I modify the test program as follows:

> cat test.c

#include <stdio.h>
int main(void) {
printf("%s\n", "Hello");
fclose(stdout);
return (0);
}

and I recompile it:

> gcc -o test test.c
> valgrind --leak-check=yes --show-reachable=yes -v ./test

==1846== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==1846== malloc/free: in use at exit: 0 bytes in 0 blocks.
==1846== malloc/free: 1 allocs, 1 frees, 4096 bytes allocated.

My question are the following:
- is it normal or is it likely to be a bug in my implementation of the C
library?
- is it safe to fclose stdout before returning to the OS?

Thanks!

--
Pietro Cerutti

PGP Public Key:
http://gahr.ch/pgp

David Resnick 08-20-2007 04:02 PM

Re: safe to fclose stdout to avoid memory leak?
 
On Aug 20, 11:35 am, Pietro Cerutti <g...@gahr.ch> wrote:
> Hi group,
> I just noticed that a malloc w/out relative free occurs in the standard
> C library (or at least, on my implementation of it).
>
> > cat test.c

>
> #include <stdio.h>
> int main(void) {
> printf("%s\n", "Hello");
> return (0);
>
> }
> > gcc -o test test.c
> > valgrind --leak-check=yes --show-reachable=yes -v ./test

>
> [snip bla bla]
> 4096 bytes in 1 blocks are still reachable in loss record 1 of 1
> at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
> by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
> by 0x3C116E77: __swsetup (in /lib/libc.so.6)
> by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)
>
> Now, if I modify the test program as follows:
>
> > cat test.c

>
> #include <stdio.h>
> int main(void) {
> printf("%s\n", "Hello");
> fclose(stdout);
> return (0);
>
> }
>
> and I recompile it:
>
> > gcc -o test test.c
> > valgrind --leak-check=yes --show-reachable=yes -v ./test

>
> ==1846== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
> ==1846== malloc/free: in use at exit: 0 bytes in 0 blocks.
> ==1846== malloc/free: 1 allocs, 1 frees, 4096 bytes allocated.
>
> My question are the following:
> - is it normal or is it likely to be a bug in my implementation of the C
> library?
> - is it safe to fclose stdout before returning to the OS?
>
> Thanks!
>
> --
> Pietro Cerutti
>
> PGP Public Key:http://gahr.ch/pgp


It is fine to close stdout. As to the valgrind's complaint, consider
this code.

#include <stdlib.h>
static char *foo;
int main(void)
{
foo=malloc(4);
return 0;
}

The memory returned by malloc and pointed to by foo is still
"reachable". It is not "leaked", there is a good pointer to it. If
you inserted foo=NULL; after the malloc line, then it would be
leaked. Apparently, the library is creating a buffer associated with
stdout when stdout is first used and is keeping a pointer to that
buffer until stdout is explicitly closed. Sounds harmless enough.
Memory that is still "reachable" is not leaked per se, though it can
still be a problem if, for example, you have a data structure like a
hash table growing without bounds...

-David


Eric Sosman 08-20-2007 04:08 PM

Re: safe to fclose stdout to avoid memory leak?
 
Pietro Cerutti wrote On 08/20/07 11:35,:
> Hi group,
> I just noticed that a malloc w/out relative free occurs in the standard
> C library (or at least, on my implementation of it).
>
>
>>cat test.c

>
> #include <stdio.h>
> int main(void) {
> printf("%s\n", "Hello");
> return (0);
> }
>
>
>>gcc -o test test.c
>>valgrind --leak-check=yes --show-reachable=yes -v ./test

>
> [snip bla bla]
> 4096 bytes in 1 blocks are still reachable in loss record 1 of 1
> at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
> by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
> by 0x3C116E77: __swsetup (in /lib/libc.so.6)
> by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)
>
> Now, if I modify the test program as follows:
>
>
>>cat test.c

>
> #include <stdio.h>
> int main(void) {
> printf("%s\n", "Hello");
> fclose(stdout);
> return (0);
> }
>
> and I recompile it:
>
>
>>gcc -o test test.c
>>valgrind --leak-check=yes --show-reachable=yes -v ./test

>
> ==1846== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
> ==1846== malloc/free: in use at exit: 0 bytes in 0 blocks.
> ==1846== malloc/free: 1 allocs, 1 frees, 4096 bytes allocated.
>
> My question are the following:
> - is it normal or is it likely to be a bug in my implementation of the C
> library?


It is unlikely to be a bug.

> - is it safe to fclose stdout before returning to the OS?


It is safe, but note that the program might not end
when main() returns or when exit() is called. If any
functions have been registered with atexit(), they will
run after this point -- and if they try to use stdout ...

--
Eric.Sosman@sun.com

Pietro Cerutti 08-20-2007 04:19 PM

Re: safe to fclose stdout to avoid memory leak?
 
Pietro Cerutti wrote:
> Hi group,
> I just noticed that a malloc w/out relative free occurs in the standard
> C library (or at least, on my implementation of it).
>
>> cat test.c

> #include <stdio.h>
> int main(void) {
> printf("%s\n", "Hello");
> return (0);
> }
>
>> gcc -o test test.c
>> valgrind --leak-check=yes --show-reachable=yes -v ./test

> [snip bla bla]
> 4096 bytes in 1 blocks are still reachable in loss record 1 of 1
> at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
> by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
> by 0x3C116E77: __swsetup (in /lib/libc.so.6)
> by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)
>
> Now, if I modify the test program as follows:
>
>> cat test.c

> #include <stdio.h>
> int main(void) {
> printf("%s\n", "Hello");
> fclose(stdout);
> return (0);
> }
>
> and I recompile it:
>
>> gcc -o test test.c
>> valgrind --leak-check=yes --show-reachable=yes -v ./test

> ==1846== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
> ==1846== malloc/free: in use at exit: 0 bytes in 0 blocks.
> ==1846== malloc/free: 1 allocs, 1 frees, 4096 bytes allocated.
>
> My question are the following:
> - is it normal or is it likely to be a bug in my implementation of the C
> library?
> - is it safe to fclose stdout before returning to the OS?
>
> Thanks!
>


Thank you David and Eric for your points!

--
Pietro Cerutti

PGP Public Key:
http://gahr.ch/pgp

Chris Torek 08-21-2007 06:19 AM

Re: safe to fclose stdout to avoid memory leak?
 
In article <2df02$46c9b4bf$50dabbcd$18013@news.hispeed.ch>
Pietro Cerutti <gahr@gahr.ch> wrote:
>Hi group,
>I just noticed that a malloc w/out relative free occurs in the standard
>C library (or at least, on my implementation of it).

[snippage, some output from valgrind remaining:]
>4096 bytes in 1 blocks are still reachable in loss record 1 of 1
>at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
>by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
>by 0x3C116E77: __swsetup (in /lib/libc.so.6)
>by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)


These function names suggest that your libc uses the stdio code I
wrote for 4.xBSD (or something closely related / descended; I think
my printf engine was originally named __svfprintf, for instance).

Originally, I had -- or was going to have -- the code called at
program exit iterate over all the open FILE data structures and
"fclose" them. This would release the memory allocated by
__smakebuf(), and also use the system's "close file" call on the
associated file descriptor (normally fd 1). Someone pointed out,
though, that it is "more efficient" on the BSD systems to just
fflush() these files, to force pending output to appear, and then
use the system's "exit" call to release all memory (including
malloc()ed memory, without going through free() at all) and close
all files (without using the system's "close file" call).

If you or I were writing Standard C, this is not such a great idea.
But I was not writing Standard C; I was implementing the C library
in a system-specific manner. Because I was writing system-specific
code, I could depend on behavior not prescribed by the C Standard,
such as "memory gets freed automatically when the program terminates"
and "files get closed automatically when the program terminates".
In other words, as the implementor, I am *allowed* to cheat. :-)

(Note also that the function names I used are all in the implementor's
namespace. I used names beginning with double underscores, which
you -- as a "user" programmer -- must avoid. I, as an "implementor"
programmer, must avoid any names that you can use. The double
underscore prefix safely hides me from you, and you from me, except
at the interfaces required by Standard C: fopen, fclose, and so
on, in this case.)

>My question are the following:
>- is it normal or is it likely to be a bug in my implementation of the C
>library?


It is not really "normal" but it is not a "bug" either. Instead,
it is a deliberate violation done in the name of efficiency,
"knowing" various things (which I hope are still true today :-) )
about the system. (Anyone modifying the underlying system in a
way that breaks these assumptions must also modify the C implementation.)

>- is it safe to fclose stdout before returning to the OS?


It should be safe, but unnecessary.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

Richard Tobin 08-21-2007 09:16 AM

Re: safe to fclose stdout to avoid memory leak?
 
In article <fae04v094d@news3.newsguy.com>,
Chris Torek <nospam@torek.net> wrote:

>But I was not writing Standard C; I was implementing the C library
>in a system-specific manner. Because I was writing system-specific
>code, I could depend on behavior not prescribed by the C Standard,
>such as "memory gets freed automatically when the program terminates"
>and "files get closed automatically when the program terminates".
>In other words, as the implementor, I am *allowed* to cheat. :-)


If one were writing the code today (rather than in the 1980s) I think
the advantage of having memory checkers show no leaks at exit would
outweigh the (now insignificant) efficiency gain.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.

Pietro Cerutti 08-21-2007 10:27 AM

Re: safe to fclose stdout to avoid memory leak?
 
Chris Torek wrote:
> In article <2df02$46c9b4bf$50dabbcd$18013@news.hispeed.ch>
> Pietro Cerutti <gahr@gahr.ch> wrote:
>> Hi group,
>> I just noticed that a malloc w/out relative free occurs in the standard
>> C library (or at least, on my implementation of it).

> [snippage, some output from valgrind remaining:]
>> 4096 bytes in 1 blocks are still reachable in loss record 1 of 1
>> at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
>> by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
>> by 0x3C116E77: __swsetup (in /lib/libc.so.6)
>> by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)

>
> These function names suggest that your libc uses the stdio code I
> wrote for 4.xBSD (or something closely related / descended; I think
> my printf engine was originally named __svfprintf, for instance).
>
> Originally, I had -- or was going to have -- the code called at
> program exit iterate over all the open FILE data structures and
> "fclose" them. This would release the memory allocated by
> __smakebuf(), and also use the system's "close file" call on the
> associated file descriptor (normally fd 1). Someone pointed out,
> though, that it is "more efficient" on the BSD systems to just
> fflush() these files, to force pending output to appear, and then
> use the system's "exit" call to release all memory (including
> malloc()ed memory, without going through free() at all) and close
> all files (without using the system's "close file" call).
>
> If you or I were writing Standard C, this is not such a great idea.
> But I was not writing Standard C; I was implementing the C library
> in a system-specific manner. Because I was writing system-specific
> code, I could depend on behavior not prescribed by the C Standard,
> such as "memory gets freed automatically when the program terminates"
> and "files get closed automatically when the program terminates".
> In other words, as the implementor, I am *allowed* to cheat. :-)
>
> (Note also that the function names I used are all in the implementor's
> namespace. I used names beginning with double underscores, which
> you -- as a "user" programmer -- must avoid. I, as an "implementor"
> programmer, must avoid any names that you can use. The double
> underscore prefix safely hides me from you, and you from me, except
> at the interfaces required by Standard C: fopen, fclose, and so
> on, in this case.)
>
>> My question are the following:
>> - is it normal or is it likely to be a bug in my implementation of the C
>> library?

>
> It is not really "normal" but it is not a "bug" either. Instead,
> it is a deliberate violation done in the name of efficiency,
> "knowing" various things (which I hope are still true today :-) )
> about the system. (Anyone modifying the underlying system in a
> way that breaks these assumptions must also modify the C implementation.)
>
>> - is it safe to fclose stdout before returning to the OS?

>
> It should be safe, but unnecessary.


Hi Christ,
thank you very much for your exhaustive explanation.
So, in short terms, what you're saying is that valgrind notices that
memory isn't deallocated at program exit (which is true) because it gets
eventually free'd by the OS, so I don't have to worry about memory
leaks, right?

Regards,

--
Pietro Cerutti

PGP Public Key:
http://gahr.ch/pgp

Antoninus Twink 08-30-2007 09:37 PM

Re: safe to fclose stdout to avoid memory leak?
 
On 21 Aug 2007 at 10:27, Pietro Cerutti wrote:
> Chris Torek wrote:
>> In article <2df02$46c9b4bf$50dabbcd$18013@news.hispeed.ch>
>> Pietro Cerutti <gahr@gahr.ch> wrote:
>>> Hi group,
>>> I just noticed that a malloc w/out relative free occurs in the standard
>>> C library (or at least, on my implementation of it).

>> [snippage, some output from valgrind remaining:]
>>> 4096 bytes in 1 blocks are still reachable in loss record 1 of 1
>>> at 0x3C03B18F: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
>>> by 0x3C116FD2: __smakebuf (in /lib/libc.so.6)
>>> by 0x3C116E77: __swsetup (in /lib/libc.so.6)
>>> by 0x3C10BF7F: __vfprintf (in /lib/libc.so.6)

>>
>> These function names suggest that your libc uses the stdio code I
>> wrote for 4.xBSD (or something closely related / descended; I think
>> my printf engine was originally named __svfprintf, for instance).
>>
>> Originally, I had -- or was going to have -- the code called at
>> program exit iterate over all the open FILE data structures and
>> "fclose" them. This would release the memory allocated by
>> __smakebuf(), and also use the system's "close file" call on the
>> associated file descriptor (normally fd 1). Someone pointed out,
>> though, that it is "more efficient" on the BSD systems to just
>> fflush() these files, to force pending output to appear, and then
>> use the system's "exit" call to release all memory (including
>> malloc()ed memory, without going through free() at all) and close
>> all files (without using the system's "close file" call).
>>
>> If you or I were writing Standard C, this is not such a great idea.
>> But I was not writing Standard C; I was implementing the C library
>> in a system-specific manner. Because I was writing system-specific
>> code, I could depend on behavior not prescribed by the C Standard,
>> such as "memory gets freed automatically when the program terminates"
>> and "files get closed automatically when the program terminates".
>> In other words, as the implementor, I am *allowed* to cheat. :-)
>>
>> (Note also that the function names I used are all in the implementor's
>> namespace. I used names beginning with double underscores, which
>> you -- as a "user" programmer -- must avoid. I, as an "implementor"
>> programmer, must avoid any names that you can use. The double
>> underscore prefix safely hides me from you, and you from me, except
>> at the interfaces required by Standard C: fopen, fclose, and so
>> on, in this case.)
>>
>>> My question are the following:
>>> - is it normal or is it likely to be a bug in my implementation of the C
>>> library?

>>
>> It is not really "normal" but it is not a "bug" either. Instead,
>> it is a deliberate violation done in the name of efficiency,
>> "knowing" various things (which I hope are still true today :-) )
>> about the system. (Anyone modifying the underlying system in a
>> way that breaks these assumptions must also modify the C implementation.)
>>
>>> - is it safe to fclose stdout before returning to the OS?

>>
>> It should be safe, but unnecessary.

>
> Hi Christ,
> thank you very much for your exhaustive explanation.
> So, in short terms, what you're saying is that valgrind notices that
> memory isn't deallocated at program exit (which is true) because it gets
> eventually free'd by the OS, so I don't have to worry about memory
> leaks, right?


I believe that is false on some versions of MS-DOS.

>
> Regards,
>


--
Search the web: http://www.google.com


All times are GMT. The time now is 02:04 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.