472,787 Members | 1,552 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,787 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 6469
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: viza | last post by:
Hi! Is there any harm/advantage to closing the standard input stream if I am not going to read from it again? I have: if(blah) fileptr=fopen(blah); else
11
by: Marcus Jacobs | last post by:
Dear Group I have encountered a problem with fclose and I am wondering if anyone could provide some insight about this problem to me. Currently, I am working on a small personal project that is...
19
by: lihua | last post by:
Hi, Group! I got one question here: We all know that fclose() must be called after file operations to avoid unexpected errors.But there are really cases when you forget to do that!Just like...
1
by: William Sullivan | last post by:
I'm trying to nail down some issues with the cache in my application. Currently, I have an object that stands between my business logic and database logic called CacheLogic (cute, no?). ...
2
by: Jeff Chan | last post by:
I have read the documentation from msdn to try to understanding the concept of "Type safe". Would someone give me an example of code segment illustrating what is *Non* type safe? Many Thanks,...
8
by: ais523 | last post by:
I use this function that I wrote for inputting strings. It's meant to return a pointer to mallocated memory holding one input string, or 0 on error. (Personally, I prefer to use 0 to NULL when...
10
by: Andrew Trevorrow | last post by:
No response to my last message, so I'll try a different tack... Does anyone know of, or even better, has anyone here written a C++ application for Mac/Windows that allows users to run Python...
20
by: David Mathog | last post by:
A program of mine writes to a tape unit. Output can be either through stdout or through a file opened with fopen(). When all the data is transferred to tape the program needs to close the output...
16
by: Bill Cunningham | last post by:
Is it really necessary to check the return type (int) or fclose ? fopen I can understand but what about using fflsuh(fp); /* fopen's pointer */ fclose(fp); Would that take care of any...
0
by: Rina0 | last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

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.