|
From: Nicolas B. <nbi...@gm...> - 2008-02-21 22:07:59
|
I'm running my code through valgrind and it report an error that I can't
correct. I was able to isolate the problem though with a simple code.
I want to dump to a (binary) file the content of a structure. Then valgrind
report a strange error about memory not allocated. It seems valgrind don't
like it when their is a character array in the structure. Here is the error:
==7743== Syscall param write(buf) points to uninitialised byte(s)
==7743== at 0x5671080: __write_nocancel (in /lib/libc-2.7.so)
==7743== by 0x56243C2: _IO_file_write@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
==7743== by 0x5624074: new_do_write (in /lib/libc-2.7.so)
==7743== by 0x5624363: _IO_do_write@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
==7743== by 0x562532F: _IO_file_close_it@@GLIBC_2.2.5 (in /lib/libc-
2.7.so)
==7743== by 0x5619409: fclose@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
==7743== by 0x400B4D: main (in /tmp/test/a.out)
==7743== Address 0x401d009 is not stack'd, malloc'd or (recently) free'd
The code is:
#include <stdio.h>
#include <string.h>
struct mystruct
{
int age;
char name[10];
int intarray[2];
};
int main()
{
mystruct s;
FILE *f;
strcpy(s.name,"John");
s.age = 25;
s.intarray[0] = 11;
s.intarray[1] = 12;
f = fopen("test.dat","wb");
fwrite(&s,1,sizeof(s),f);
fclose(f);
return 0;
}
As you can see, the code is really simple... If "char name[100];" is not
present in the structure, valgrind don't report error.
Is this a problem with valgrind or is it really not valid?? Why is the
integer array correct but not the character array? Is there something I'm
missing or maybe it is a bug with valgrind?
Thank you very much.
Nicolas
|
|
From: Nicholas N. <nj...@cs...> - 2008-02-21 22:47:41
|
On Thu, 21 Feb 2008, Nicolas Bigaouette wrote:
> I want to dump to a (binary) file the content of a structure. Then valgrind
> report a strange error about memory not allocated. It seems valgrind don't
> like it when their is a character array in the structure. Here is the error:
> ==7743== Syscall param write(buf) points to uninitialised byte(s)
> ==7743== at 0x5671080: __write_nocancel (in /lib/libc-2.7.so)
> ==7743== by 0x56243C2: _IO_file_write@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
> ==7743== by 0x5624074: new_do_write (in /lib/libc-2.7.so)
> ==7743== by 0x5624363: _IO_do_write@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
> ==7743== by 0x562532F: _IO_file_close_it@@GLIBC_2.2.5 (in /lib/libc-
> 2.7.so)
> ==7743== by 0x5619409: fclose@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
> ==7743== by 0x400B4D: main (in /tmp/test/a.out)
> ==7743== Address 0x401d009 is not stack'd, malloc'd or (recently) free'd
>
> struct mystruct
> {
> int age;
> char name[10];
> int intarray[2];
> };
The C compiler will insert padding in this struct -- 2 empty bytes between
the end of 'name' and the start of 'intarray'. This is so that 'intarray'
is aligned. Those two bytes aren't assigned by your program, so they're
undefined, and Valgrind complains about them when they are used as inputs to
'write'.
The easiest workaround is to call 'memset' on the struct to zero all the
bytes in it, just after it is declared. That way the two padding bytes will
get initialised.
Nick
|
|
From: Nicolas B. <nbi...@gm...> - 2008-02-21 22:59:04
|
Wow thank you! I need to read more on structure alignment/padding...
I'm memset()'ing my structure to 0 and don't have that problem anymore.
Thank you very much! :) Here is my (real) code:
InputParameters params;
memset(¶ms, 0, sizeof(InputParameters));
Thanx again ;)
Nicolas
2008/2/21, Nicholas Nethercote <nj...@cs...>:
>
> On Thu, 21 Feb 2008, Nicolas Bigaouette wrote:
>
> > I want to dump to a (binary) file the content of a structure. Then
> valgrind
> > report a strange error about memory not allocated. It seems valgrind
> don't
> > like it when their is a character array in the structure. Here is the
> error:
> > ==7743== Syscall param write(buf) points to uninitialised byte(s)
> > ==7743== at 0x5671080: __write_nocancel (in /lib/libc-2.7.so)
> > ==7743== by 0x56243C2: _IO_file_write@@GLIBC_2.2.5 (in /lib/libc-
> 2.7.so)
> > ==7743== by 0x5624074: new_do_write (in /lib/libc-2.7.so)
> > ==7743== by 0x5624363: _IO_do_write@@GLIBC_2.2.5 (in /lib/libc-2.7.so
> )
> > ==7743== by 0x562532F: _IO_file_close_it@@GLIBC_2.2.5 (in /lib/libc-
> > 2.7.so)
> > ==7743== by 0x5619409: fclose@@GLIBC_2.2.5 (in /lib/libc-2.7.so)
> > ==7743== by 0x400B4D: main (in /tmp/test/a.out)
> > ==7743== Address 0x401d009 is not stack'd, malloc'd or (recently)
> free'd
> >
>
> > struct mystruct
> > {
> > int age;
> > char name[10];
> > int intarray[2];
> > };
>
>
> The C compiler will insert padding in this struct -- 2 empty bytes between
> the end of 'name' and the start of 'intarray'. This is so that 'intarray'
> is aligned. Those two bytes aren't assigned by your program, so they're
> undefined, and Valgrind complains about them when they are used as inputs
> to
> 'write'.
>
> The easiest workaround is to call 'memset' on the struct to zero all the
> bytes in it, just after it is declared. That way the two padding bytes
> will
> get initialised.
>
> Nick
>
|