![]() |
splint: where is the memory leak?
Hi everyone. I'm scratching my head and can't understand why I'm
getting a warning from splint on this bit of code: 1 #include <stdio.h> 2 #include <ctype.h> 3 4 static char *strtolower( char *str ) 5 { 6 char *s; 7 8 for ( s = str; *s; ++s ) 9 *s = tolower( *s ); 10 11 return str; 12 } 13 14 int main( void ) 15 { 16 char msg[] = "Hello world"; 17 18 printf( "%s\n", strtolower( msg ) ); 19 return 0; 20 } $ splint test.c Splint 3.1.1 --- 03 Sep 2009 test.c: (in function strtolower) test.c:8:20: Test expression for for not boolean, type char: *s Test expression type is not boolean. (Use -predboolothers to inhibit warning) test.c:11:12: Implicitly temp storage str returned as implicitly only: str Temp storage (associated with a formal parameter) is transferred to a non-temporary reference. The storage may be released or new aliases created. (Use -temptrans to inhibit warning) test.c: (in function main) test.c:18:21: New fresh storage (type char *) passed as implicitly temp (not released): strtolower(msg) A memory leak has been detected. Storage allocated locally is not released before the last reference to it is lost. (Use -mustfreefresh to inhibit warning) Finished checking --- 3 code warnings $ gcc -ansi -pedantic -Wall test.c -o test $ ./test hello world $ Okay, so splint warns me that it has detected a memory leak in the printf call, which itself calls the function strtolower. I can't see it - I am only returning the same address that was passed to the function as a parameter. No new memory is being allocated, so I cannot understand why there would be a memory leak? Can any one guide me on why there's a memory leak here? How do I correct it or code around it? Or is splint in error? TIA- Kevin |
Re: splint: where is the memory leak?
On 2010-01-08, kevin <mess_kevin_@colstate.edu> wrote:
> Hi everyone. I'm scratching my head and can't understand why I'm > getting a warning from splint on this bit of code: Splint is a program that, on unadorned C source, produces reams and reams of false positives about imaginary situations. To use splint properly, you have to write your programs in a special language which consists of C, plus splint annotations written C comments. The C implementation discards the comments, but they are part of the splint+C language. Splint is almost totally useless when applied to unannotated C source. To learn about this Splint annotation language, you have to---surprise!---read the Splint manual. > 1 #include <stdio.h> > 2 #include <ctype.h> > 3 > 4 static char *strtolower( char *str ) By the way, don't do this. Identifiers beginning with "str" are reserved for use as external names by the C standard, for the library. > > 5 { > 6 char *s; > 7 > 8 for ( s = str; *s; ++s ) > 9 *s = tolower( *s ); > 10 > 11 return str; > 12 } > 13 > 14 int main( void ) > 15 { > 16 char msg[] = "Hello world"; > 17 > 18 printf( "%s\n", strtolower( msg ) ); > 19 return 0; > 20 } So here, by default, this situation looks like a leak: printf( "%s\n", strtolower( msg ) ); The reason is that strtolower(msg) suspiciously looks like a function that allocates and returns new storage. In fact, a strtolower function could work by leaving the origianl string alone and returning a lower-case version, in which case you would have a memory leak. splint will not analyze your C code to confirm or refute its suspicion; it relies on the annotations. You must somehow tell it that strtolower does not allocate new memory. Annotations suck, but one useful thing about them is that (like C declarations), they allow translation units of the program to be checked without access to other translation units. Imagine if strtolower was in a third party library, for which you have only a header and binary code. How can the static checker decide whether or not that printf has a memory leak? Only in two possible ways: analyze the compiled binary code, or rely on special annotations added to the header. |
Re: splint: where is the memory leak?
On 1/8/2010 2:31 PM, kevin wrote:
> Hi everyone. I'm scratching my head and can't understand why I'm getting > a warning from splint on this bit of code: > > 1 #include <stdio.h> > 2 #include <ctype.h> > 3 > 4 static char *strtolower( char *str ) > 5 { > 6 char *s; > 7 > 8 for ( s = str; *s; ++s ) > 9 *s = tolower( *s ); > 10 > 11 return str; > 12 } > 13 > 14 int main( void ) > 15 { > 16 char msg[] = "Hello world"; > 17 > 18 printf( "%s\n", strtolower( msg ) ); > 19 return 0; > 20 } > > $ splint test.c > Splint 3.1.1 --- 03 Sep 2009 > > test.c: (in function strtolower) > test.c:8:20: Test expression for for not boolean, type char: *s > Test expression type is not boolean. (Use -predboolothers to inhibit > warning) Translation: "splint is a style tyrant." > test.c:11:12: Implicitly temp storage str returned as implicitly only: str > Temp storage (associated with a formal parameter) is transferred to a > non-temporary reference. The storage may be released or new aliases > created. > (Use -temptrans to inhibit warning) Translation: [beyond my power to translate; I can find no meaning and no sense in this message]. > test.c: (in function main) > test.c:18:21: New fresh storage (type char *) passed as implicitly temp > (not > released): strtolower(msg) > A memory leak has been detected. Storage allocated locally is not released > before the last reference to it is lost. (Use -mustfreefresh to inhibit > warning) Translation: "splint is wrong." > Finished checking --- 3 code warnings Translation: "splint overlooked both the infringement of the implementation's name space and the code's only ACTUAL ERROR in line 9." > Or is splint in error? I'm not familiar with splint, but on the evidence presented here it deserves to be, er, cast aside. -- Eric Sosman esosman@ieee-dot-org.invalid |
Re: splint: where is the memory leak?
Eric Sosman <esosman@ieee-dot-org.invalid> writes:
>> 4 static char *strtolower( char *str ) > Translation: [beyond my power to translate; I can find no >meaning and no sense in this message]. It might mean that a naïve author might write: if( a = malloc( 10 )) { strcpy( a, "hi!" ); b = strtolower( a ); free( a ); puts( b ); } I.e., it needs to be documented that the result is /the same pointer/ as the argument. |
Re: splint: where is the memory leak?
On Fri, 08 Jan 2010 15:35:31 -0500, Eric Sosman
<esosman@ieee-dot-org.invalid> wrote: [snippety snip] > I'm not familiar with splint, but on the evidence presented >here it deserves to be, er, cast aside. An int-arresting pun for a Friday afternoon. Touché, sir! -- Rich Webb Norfolk, VA |
Re: splint: where is the memory leak?
Rich Webb wrote:
> On Fri, 08 Jan 2010 15:35:31 -0500, Eric Sosman > <esosman@ieee-dot-org.invalid> wrote: > > [snippety snip] >> I'm not familiar with splint, but on the evidence presented >> here it deserves to be, er, cast aside. > > An int-arresting pun for a Friday afternoon. Touché, sir! Or a static Saturday morning! -- Ian Collins |
Re: splint: where is the memory leak?
Thank you everyone for your reply. I'm glad I didn't completely
misunderstand. I appreciate your comments. Kevin |
Re: splint: where is the memory leak?
Kaz Kylheku wrote: > > Splint is almost totally useless when applied to unannotated C source. > Yes, but "splint -weak" is actually pretty useful on code without annotations. |
Re: splint: where is the memory leak?
In article <c07b1c45-e536-47cd-8151-751fa081a2f2@
22g2000yqr.googlegroups.com>, bkatt@cfl.rr.com says... > > Kaz Kylheku wrote: > > > > Splint is almost totally useless when applied to unannotated C source. > > > > Yes, but "splint -weak" is actually pretty useful on code without > annotations. Even the default setting is fine if you know when to ignore it. |
Re: splint: where is the memory leak?
Dann Corbit <dcorbit@connx.com> wrote:
> 22g2000yqr.googlegroups.com>, bkatt@cfl.rr.com says... > > Kaz Kylheku wrote: > > > > > > Splint is almost totally useless when applied to unannotated C source. > > > > Yes, but "splint -weak" is actually pretty useful on code without > > annotations. > > Even the default setting is fine if you know when to ignore it. Myeah, but that doesn't say much. Even Dubya's speeches are fine if you know when to ignore them. When "when" becomes "always", it is useless. Richard |
| All times are GMT. The time now is 07:42 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.