471,305 Members | 1,257 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,305 software developers and data experts.

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
Aug 20 '07 #1
7 6254
On Aug 20, 11:35 am, Pietro Cerutti <g...@gahr.chwrote:
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

Aug 20 '07 #2
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 ...

--
Er*********@sun.com
Aug 20 '07 #3
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
Aug 20 '07 #4
In article <2d***************************@news.hispeed.ch>
Pietro Cerutti <ga**@gahr.chwrote:
>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.
Aug 21 '07 #5
In article <fa********@news3.newsguy.com>,
Chris Torek <no****@torek.netwrote:
>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.
Aug 21 '07 #6
Chris Torek wrote:
In article <2d***************************@news.hispeed.ch>
Pietro Cerutti <ga**@gahr.chwrote:
>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
Aug 21 '07 #7
On 21 Aug 2007 at 10:27, Pietro Cerutti wrote:
Chris Torek wrote:
>In article <2d***************************@news.hispeed.ch>
Pietro Cerutti <ga**@gahr.chwrote:
>>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
Aug 30 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by viza | last post: by
11 posts views Thread by Marcus Jacobs | last post: by
1 post views Thread by William Sullivan | last post: by
2 posts views Thread by Jeff Chan | last post: by
8 posts views Thread by ais523 | last post: by
10 posts views Thread by Andrew Trevorrow | last post: by
20 posts views Thread by David Mathog | last post: by
16 posts views Thread by Bill Cunningham | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.