|
From: David C. <dcc...@ac...> - 2013-02-11 07:34:36
|
On 2/10/2013 9:55 PM, David Hourn (DTH Design) wrote:
> I am new to C and Valgrind, so I can't understand why I am getting an
> error message on what seems like a pretty standard if statement.
>
> Basically I want to strip the newline character, '\n', from the value
> fgets returns to me. Pretty much everywhere I could find said the
> recommended way to do this was something like this: (getInput is a
> function I have written where fgets resides and it does some validation)
>
> char *getInputNoNewline(int max, char message[]) { static char* input;
> int maxchars = max+ADDCHARS input = (char*)malloc(maxchars); input =
> getInput(max, message); if (input[strlen(input) - 1] == '\n') {
> input[strlen(input) - 1] = '\0'; } return input; }
We prefer that you submit a full listing of the failing program if you
can; otherwise your discussion is vulnerable to cut and paste errors.
For example, you are missing a semicolon after the maxchars declaration
in the snippet above (a syntax error). There could be many more
differences between what you've sent and what you are actually running.
I see a possible memory leak, which may also be due to cut and paste -
every time you call getInputNoNewline(), you are allocating a new buffer
and storing a pointer to it in a static variable. Then you overwrite
that pointer with the return value from getInput(), losing track of the
memory just allocated. Usually static variables are used for objects
that will have a long lifetime; you allocate it once (perhaps
reallocating it when it needs to grow) and then pass around a pointer to
use. The pointer will usually not be overwritten each time.
> The if statement is giving me 57 errors from 6 contexts.
>
> Running in verbose mode a typical error is:
>
> ==18533== 3 errors in context 3 of 18:
> ==18533== Invalid read of size 1
> ==18533== at 0x100000BF0: getInputNoNewline (start.c:44)
> ==18533== by 0x100000D2A: main (start.c:61)
> ==18533== Address 0x10027f434 is 4 bytes inside a block of size 6 free'd
> ==18533== at 0x10000FE9F: free (vg_replace_malloc.c:366)
> ==18533== by 0x100000B88: getInput (start.c:35)
> ==18533== by 0x100000BCD: getInputNoNewline (start.c:43)
> ==18533== by 0x100000D2A: main (start.c:61)
The call stack ("context") here says that getInput() is releasing the
memory being read by getInputNoNewline(). main() is calling
getInputNoNewline() which is calling getInput() which is calling free()
in file start.c, line 35. Given the question about a possible memory
leak above, it sounds like you are not reading from/writing into the
buffer that getInputNoNewline() is creating; you are writing into
something else that is freed before getInputNoNewline() regains control.
>
> The statement replacing '\n' with '\o' is giving me 75 errors from 12
> contexts.
>
> Typical error message:
>
> ==18533== 18 errors in context 17 of 18:
> ==18533== Invalid read of size 1
> ==18533== at 0x100011503: strlen (mc_replace_strmem.c:282)
> ==18533== by 0x100000C0D: getInputNoNewline (start.c:45)
> ==18533== by 0x100000CF8: main (start.c:59)
> ==18533== Address 0x10027f361 is 1 bytes inside a block of size 50 free'd
> ==18533== at 0x10000FE9F: free (vg_replace_malloc.c:366)
> ==18533== by 0x100000B88: getInput (start.c:35)
> ==18533== by 0x100000BCD: getInputNoNewline (start.c:43)
> ==18533== by 0x100000CF8: main (start.c:59)
>
> Are these errors that valgrind is giving me likely to cause any errors
> down the track as programs become more complex?
>
The call stack is the same; most likely this is the exact same problem.
You have a pointer to freed memory and you are dereferencing it - first
a read and then a write.
Very definitely you are going to have problems with this code.
--
David Chapman dcc...@ac...
Chapman Consulting -- San Jose, CA
Software Development Done Right.
www.chapman-consulting-sj.com
|