strings and malloc()

M

Mark

Hello

Given this little piece of code.

#include <stdio.h>
static char *mkw(void)
{
return "xyz";
}

int main(void)
{
char *s = NULL;
s = mkw();
printf("%s\n", s);
return 0;
}

Running 'splint' ("splint foo.c") results in complaints:

Splint 3.1.1 --- 11 Sep 2006

a.c: (in function mkw)
a.c:5:9: Observer storage returned without qualification: "xyz"
Observer storage is transferred to a non-observer reference. (Use
-observertrans to inhibit warning)
a.c:5:9: Storage becomes observer
a.c: (in function main)
a.c:14:11: Fresh storage s not released before return
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)
a.c:11:2: Fresh storage s created

Finished checking --- 2 code warningsSplint 3.1.1 --- 11 Sep 2006

What's wrong with it? GCC happily compiles though. I read that sometimes
'splint' may be too picky, is this the case?
Thanks in advance.
 
E

Eric Sosman

Mark said:
Hello

Given this little piece of code.

#include <stdio.h>
static char *mkw(void)
{
return "xyz";
}

int main(void)
{
char *s = NULL;
s = mkw();
printf("%s\n", s);
return 0;
}

Are you sure this is the actual code in question? Three
things seem odd:

- The mention of malloc() in your subject line even though
there are no malloc() calls in the code (and <stdlib.h> isn't
included, either),

- splint's references to "fresh storage" and "memory leak"
even though no dynamic memory is allocated anywhere,

- splint's complaints about the file "a.c" even though
the command line tells it to check "foo.c" (this may be the
most suggestive of the three oddities ...)

Is it possible you've showed us something other than what
you showed splint?
 
B

Ben Bacarisse

Eric Sosman said:
Are you sure this is the actual code in question?

On my system splint gives the exact errors reported by the op when
given this code.
 
E

Eric Sosman

Ben said:
On my system splint gives the exact errors reported by the op when
given this code.

Even to the extent of complaining about problems in the
file "a.c" when given the command line "splint foo.c", as
reported in the original post? I'm not a splint user, but
perhaps that's all to the good: A tool that snoops files it
hasn't been told to and complains about allocations where
none occur may just be a troublemaker.
 
J

jameskuyper

Ben said:
On my system splint gives the exact errors reported by the op when
given this code.

Eric raised four points that suggested a mismatch between the
problematic code and the code that Mark gave us. I can confirm from
running splint on the code Mark gave us that one of those points
doesn't hold up:
- splint's references to "fresh storage" and "memory leak"
even though no dynamic memory is allocated anywhere,

I don't know why, but I have confirmed that splint does do this. This
may explain Mark's reference, in the Subject: header, to malloc().

I still get messages that refer to "foo.c", not "a.c". Also, I got the
line numbers to match only by moving a blank line, somewhere between
the use of "xyz" and the return from main(), to a position after the
declaration of s. Therefore, Mark clearly did not simply cut-and-paste
the source code into his message.

Also, I can't get the column numbers in the error messages to match
without replacing the leading four blanks on some of the lines with
tab characters. However, that could easily be due to issues with his
news reader or his source code editor.
 
B

Ben Bacarisse

Eric Sosman said:
Even to the extent of complaining about problems in the
file "a.c" when given the command line "splint foo.c", as
reported in the original post?

No. I was trying to be helpful by suggesting that the inconsistencies
you spotted did not affect the substantive points of the original
message. Yes, differences in the file name and input spacing do alter
the exact output as one would expect.
 
J

James Kuyper

Ben said:
Eric Sosman said:
Ben said:
[... code and messages snipped ...]
Are you sure this is the actual code in question?
On my system splint gives the exact errors reported by the op when
given this code.
Even to the extent of complaining about problems in the
file "a.c" when given the command line "splint foo.c", as
reported in the original post?

No. I was trying to be helpful by suggesting that the inconsistencies
you spotted did not affect the substantive points of the original
message. Yes, differences in the file name and input spacing do alter
the exact output as one would expect.

The point is, Mark's file was supposedly named "foo.c", and supposedly
contained the lines Mark quoted to us, while the evidence of the error
messages suggests that neither of those things were actually true.
Duplicating the text of the error messages is pretty much pointless if
the code you used to do it is different from the unknown code that
originally produced them.
 
B

Ben Bacarisse

James Kuyper said:
Ben said:
Eric Sosman said:
Ben Bacarisse wrote:
[... code and messages snipped ...]
Are you sure this is the actual code in question?
On my system splint gives the exact errors reported by the op when
given this code.
Even to the extent of complaining about problems in the
file "a.c" when given the command line "splint foo.c", as
reported in the original post?

No. I was trying to be helpful by suggesting that the inconsistencies
you spotted did not affect the substantive points of the original
message. Yes, differences in the file name and input spacing do alter
the exact output as one would expect.

The point is, Mark's file was supposedly named "foo.c", and supposedly
contained the lines Mark quoted to us, while the evidence of the error
messages suggests that neither of those things were actually
true.

I disagree. Mark's file was obviously called a.c and I interpreted
"splint foo.c" simply an example of the command he used. I.e. simply
to say "no flags or options". The evidence of the error messages
suggested to me that the file contained lines so similar to those
being shown, that it was worth discussing the error messages. I agree
that this is not the only interpretation of the post, but I claim that
it is not wildly illogical of me to read it this way.

If I'd been worried about the discrepancies, I'd have remarked on
them ("You mean the command was 'splint a.c'" and "the spacing in this
code is obviously not the same as in the file you actually used") but
I did not consider them significant. Obviously other people did. My
post was an attempt to say "trust me, they don't matter".
Duplicating the text of the error messages is pretty much
pointless if the code you used to do it is different from the unknown
code that originally produced them.

I don't know what to say about this. It seemed to me helpful to say
that splint complains about such code even if you add a newline here
and remove a few spaces there. Of course you are quite right that I
may be seeing exactly the same error messages from entirely different
code but that is equally true when there are no suspicious
discrepancies and it is true of every report of output or diagnostics
we see here.

If the OP had posted:

#include <stdio.h>
static char *mkw(void)
{
return "xyz";
}

int main(void)
{
char *s = NULL;
s = mkw();
printf("%s\n", s);

return 0;
}

and said that they had run "splint a.c" and got:

Splint 3.1.2 --- 07 May 2008

a.c: (in function mkw)
a.c:5:9: Observer storage returned without qualification: "xyz"
Observer storage is transferred to a non-observer reference. (Use
-observertrans to inhibit warning)
a.c:5:9: Storage becomes observer
a.c: (in function main)
a.c:14:11: Fresh storage s not released before return
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)
a.c:11:2: Fresh storage s created

Finished checking --- 2 code warnings

What would you say if I replied "I can conform this"? Would you say
that all I was doing was pointlessly recreating the error message
since I can't be sure to have the same initial text? After all, how
can I really know I have the same spacing a newlines? Has the Usenet
system interfered with some leading or trailing white space? Maybe
splint produces this output for some wildly different inputs.

If I can verify (or refute) a claim based on code that has only minor
differences in non-semantic layout, I will throw logic to the winds
and continue to do so!
 
E

Eric Sosman

Ben said:
[... why paraphrased code and/or error messages are OK ...]
If I can verify (or refute) a claim based on code that has only minor
differences in non-semantic layout, I will throw logic to the winds
and continue to do so!

Perhaps you're a better guesser than I am. Myself, I
find it frustrating to diagnose a problem in posted code
and write a recommendation on what to do about it, only to
be told "Oh, that's not what my real code looks like, and
the error message was actually something else."

The O.P.'s post was clearly inaccurate in small ways,
in ways that had "obvious" corrections. But since the minor
discrepancies *proved* that errors had crept into the
transcription, I started to wonder whether anything major
was also garbled -- particularly since the "substantive"
messages from splint looked like nonsense. (You've since
confirmed that splint does in fact report exactly this
nonsense, but that was something I didn't know at the time.)

Here's a question for you: Applying the "We can assume
the obvious corrections are made" rule to

Why doesn't my program work? Here's the code:

#include <stdio.h>
int main(void) {
prinft ("Hello, world!/n");
return 0;
}

.... would you report "It works fine for me?"
 
B

Ben Bacarisse

Eric Sosman said:
Ben said:
[... why paraphrased code and/or error messages are OK ...]
If I can verify (or refute) a claim based on code that has only minor
differences in non-semantic layout, I will throw logic to the winds
and continue to do so!

Perhaps you're a better guesser than I am.

When I do I am often wrong, so I have tried to stop doing it. In this
case I did not guess. I took splint's reported file name as the true
one and took "splint foo.c" to be no more than an example command. I,
too, was surprised by the "nonsense" output, so I clipped the code and
tried myself. Shock horror! Same output (but with slight differences
that were obviously due to white space).
Myself, I
find it frustrating to diagnose a problem in posted code
and write a recommendation on what to do about it, only to
be told "Oh, that's not what my real code looks like, and
the error message was actually something else."

Yes, that is very frustrating. But, oddly, that is exactly why I
posted! It was an attempt to say: no these messages are genuine
despite the more likely explanation that the OPs code is substantially
different to that shown.
The O.P.'s post was clearly inaccurate in small ways,
in ways that had "obvious" corrections. But since the minor
discrepancies *proved* that errors had crept into the
transcription, I started to wonder whether anything major
was also garbled -- particularly since the "substantive"
messages from splint looked like nonsense. (You've since
confirmed that splint does in fact report exactly this
nonsense, but that was something I didn't know at the time.)

Here's a question for you: Applying the "We can assume
the obvious corrections are made" rule to

Why doesn't my program work? Here's the code:

#include <stdio.h>
int main(void) {
prinft ("Hello, world!/n");
return 0;
}

... would you report "It works fine for me?"

Oh, come on! I did not say there was any "We can assume the obvious
corrections are made" rule -- that's just putting words into my mouth.
I said: "If I can verify (or refute) a claim based on code that has
only minor differences in non-semantic layout [...] I will".
 
B

Bart van Ingen Schenau

Hello

Given this little piece of code.

#include <stdio.h>
static char *mkw(void)
{
   return "xyz";

}

int main(void)
{
   char *s = NULL;
   s = mkw();
   printf("%s\n", s);
   return 0;

}

Running 'splint' ("splint foo.c") results in complaints:

As we have started a guessing game, here is my take on what these
messages mean.
As I have dealt with similar messages from pc-lint before, you might
call the following an educated guess.
Splint 3.1.1 --- 11 Sep 2006

a.c: (in function mkw)
a.c:5:9: Observer storage returned without qualification: "xyz"
Observer storage is transferred to a non-observer reference. (Use
-observertrans to inhibit warning)

This is an early warning that splint will be making wrong assumptions
later on.
Unless explicitly told otherwise, splint assumes that returning a
pointer from a function involves a transfer of ownership (and that the
returned pointer refers to allocated storage).
Here splint tells you that the default assumptions are not valid for
the pointer returned here.
a.c:5:9: Storage becomes observer
a.c: (in function main)
a.c:14:11: Fresh storage s not released before return
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)

This is a result of the assumption that returned pointers refer to
allocated storage and that ownership is transferred as well.
The assumption happens to be false, but splint does not conside the
definition of mkw while checking main, so it does not notice the
assumption is incorrect.
a.c:11:2: Fresh storage s created

Finished checking --- 2 code warningsSplint 3.1.1 --- 11 Sep 2006

What's wrong with it? GCC happily compiles though. I read that sometimes
'splint' may be too picky, is this the case?

The code is correct. splint is making some incorrect assumptions and
is warning based on those.
Thanks in advance.

Bart v Ingen Schenau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top