invalid pointer adress

F

FKothe

Hello together,

the program below shows a behavior i do not understand. When compiled
with the HX-UX11 c-comiler ( version B.11.11.04 ) v2.p in function
test_it0 points to an invalid adress and an attempt to write to this
pointer causes the program to exit with a core dump.
Output after compiling with HP c-compiler:
1. ffffff78
1. 7eff3358

When compiled with the gcc compiler the functions test_it0 and
test_it1 are working in the same ( correct ) manner.
Output when compiled with gcc:
1. 800003fffeff3730
1. 800003fffeff3730

After moving the memset command just before the printff command it
also works ok with both compilers. Even if you comment out the line
"static char BLANK_VTRNR[2] = " ";" both functions are working.

Unfortunately i found this Problem while searching for the reason of a
program crash in a larger project. Thus i cant change to another
compiler and the described work araunds ( comment out af the
declaration, moving the memset command ) does not lead to the same
effect as in this small program.

Any comment is rather appreciated.

Thanks in Advance.


---------/snip --------------------
extern void *memset(void *, int, unsigned long);

static char BLANK_VTRNR[2] = " ";

struct s1{ char c[ 81 ]; };
struct s2{ void *p; };

void test_it0( void )
{
struct s1 v1;
memset( (void*)&v1, 0, sizeof( struct s1 ) );
struct s2 v2 = { &v1.c };
printf( "1. %lx\n", v2.p );
/*
strcpy( v2.p, "Hallo ich schreibe mal was rein.." );
printf( "%s\n", v2.p );
*/
}

void test_it1(void)
{
struct s1 v1;
struct s2 v2= { &v1.c };
printf( "1. %lx\n", v2.p );
/*
strcpy( v2.p, "Hallo ich schreibe mal was rein.." );
printf( "%s\n", v2.p );
*/
}

void main ()
{
test_it0();
test_it1();
}
------------/snap/---------------
 
R

Richard Bos

the program below shows a behavior i do not understand. When compiled
with the HX-UX11 c-comiler ( version B.11.11.04 ) v2.p in function
test_it0 points to an invalid adress and an attempt to write to this
pointer causes the program to exit with a core dump.
Output after compiling with HP c-compiler:
1. ffffff78
1. 7eff3358
extern void *memset(void *, int, unsigned long);

Don't do this - #include the proper header.
static char BLANK_VTRNR[2] = " ";

(Whatever is this for? It isn't used.)
struct s1{ char c[ 81 ]; };
struct s2{ void *p; };

You cause undefined behaviour:
void test_it0( void )
{
struct s1 v1;
memset( (void*)&v1, 0, sizeof( struct s1 ) );
struct s2 v2 = { &v1.c };
printf( "1. %lx\n", v2.p );
here...

}

void test_it1(void)
{
struct s1 v1;
struct s2 v2= { &v1.c };
printf( "1. %lx\n", v2.p );

....and here...
}

void main ()

....and here.

The first two are probably (!) the most important. You cannot expect
consistent answers when you lie to printf(). You're not passing an
unsigned integer, you're passing a pointer. Replace %lx with %p, twice,
replace void main() with int main(void), return 0 from main(), and try
again.

Richard
 
F

FKothe

the program below shows a behavior i do not understand. When compiled
with the HX-UX11 c-comiler ( version B.11.11.04 ) v2.p in function
test_it0 points to an invalid adress and an attempt to write to this
pointer causes the program to exit with a core dump.
Output after compiling with HP c-compiler:
1. ffffff78
1. 7eff3358
extern void *memset(void *, int, unsigned long);

Don't do this - #include the proper header.
static char BLANK_VTRNR[2] = " ";

Yes, you are right, this declaration is absolutly unnecessary, but
commenting this line out the address of v2.p in test_it0 becomes
valid( and identical to that in test_it1 ).
To explain how i came to this program:
I am working on a larger project, which exits with a core dump. The
reason for this is that there ist a strcpy instruction to a misleading
pointer.
After I found where the pointer gets its invalid adress, i copied this
part to a new programm and included al the projects includes. As the
error still occures i startet to remove all includes and definitions
until i found the definition of "static char BLANK_VTRNR[2] = " ";"
changed the program behavior. Because i do not have any idea why this
happened I asked for help here.
After I changed the Programm in the way you suggested the same error
appears:
./test_it
1. ffffff78
1. 7eff3328

----------/snip/--------------
#include <stdio.h>

static char BLANK_VTRNR[2] = " ";

struct s1{ char c[ 81 ]; };
struct s2{ void *p; };

void test_it0( void )
{
struct s1 v1;
memset( (void*)&v1, 0, sizeof( struct s1 ) );
struct s2 v2 = { &v1.c };
printf( "1. %p\n", v2.p );
/*
strcpy( v2.p, "Hallo ich schreibe mal was rein.." );
printf( "%s\n", v2.p );
*/
}

void test_it1(void)
{
struct s1 v1;
struct s2 v2= { &v1.c };
printf( "1. %p\n", v2.p );
/*
strcpy( v2.p, "Hallo ich schreibe mal was rein.." );
printf( "%s\n", v2.p );
*/
}

int main ()
{
test_it0();
test_it1();
return 0;
}
----------/snip/--------------

Unfortunately, removing the static char BLANK_VTRNR[2] = " ";
instruction in the projekt does not have the same effect.
In the following you can see the part of the original code, which has
the described error:

int leseExterneHinweise_masch_storno( void )
{
int iRes = -1; /* Fehler */
char cfDateiMitPfad[ 1024 ];
int iDateiId;
BOOL bEofDatei = FALSE;
int iAnzSaetze = 0;

t_MaschStoExtern AktSatz;
t_ptrMaschStoExtern pNeuerSatz = NULL;
t_ptrMaschStoExtern pLetzterSatz = NULL;

t_AusdatFeldbeschreibung ExterneHinweise[ MASCHSTO_EXTERN_ANZ_FD ]
=
{ /* Typ, Laenge , Pointer zur
Variablen , Fehler */
{ AUSDAT_TYPE_STRING, MASCHSTO_ATTRNAME_LEN,
AktSatz.cfAttributName, FALSE },
{ AUSDAT_TYPE_STRING, MASCHSTO_ATTRWERT_LEN,
AktSatz.cfAttributWert, FALSE },
{ AUSDAT_TYPE_STRING, MASCHSTO_AUSGABE_LEN , AktSatz.cfAusgabe
, FALSE }
};
/* breakpoint here */
....


where
typedef struct s_AusdatFeldbeschreibung
{
short sTyp;
int iLaenge;
void *pWert;
BOOL bFehlerhaft;
} t_AusdatFeldbeschreibung;

and
typedef struct sMaschStoExtern t_MaschStoExtern;
typedef t_MaschStoExtern *t_ptrMaschStoExtern;

struct sMaschStoExtern
{
char cfAttributName[ MASCHSTO_ATTRNAME_LEN + 1 ];
char cfAttributWert[ MASCHSTO_ATTRWERT_LEN + 1 ];
char cfAusgabe[ MASCHSTO_AUSGABE_LEN + 1 ];
t_ptrMaschStoExtern pNext;
};

When having a look at the structures on the breakpoint:
&AktSatz.cfAttributName = 0x800003ffff429cb0

ExterneHinweise[0]:
sTyp = 6 ( according to definition of AUSDAT_TYPE_STRING )
iLaenge = 30 ( according to definition MASCHSTO_ATTRNAME_LEN )
pWert = 0xfffffffffffffea0 <error reading Address
0xfffffffffffffea0:Bad Address>
bFehlerhaft = 0 ( according to definition of FALSE )

But:
&ExterneHinweise[0].pWert( signed char **) 0x800003ffff429d60

(Whatever is this for? It isn't used.)
struct s1{ char c[ 81 ]; };
struct s2{ void *p; };

You cause undefined behaviour:
void test_it0( void )
{
struct s1 v1;
memset( (void*)&v1, 0, sizeof( struct s1 ) );
struct s2 v2 = { &v1.c };
printf( "1. %lx\n", v2.p );
here...

}

void test_it1(void)
{
struct s1 v1;
struct s2 v2= { &v1.c };
printf( "1. %lx\n", v2.p );

...and here...
}

void main ()

...and here.

The first two are probably (!) the most important. You cannot expect
consistent answers when you lie to printf(). You're not passing an
unsigned integer, you're passing a pointer. Replace %lx with %p, twice,
replace void main() with int main(void), return 0 from main(), and try
again.

Richard
 
R

Richard Bos

the program below shows a behavior i do not understand. When compiled
with the HX-UX11 c-comiler ( version B.11.11.04 ) v2.p in function
test_it0 points to an invalid adress and an attempt to write to this
pointer causes the program to exit with a core dump.
Output after compiling with HP c-compiler:
1. ffffff78
1. 7eff3358
extern void *memset(void *, int, unsigned long);

Don't do this - #include the proper header.
static char BLANK_VTRNR[2] = " ";

Yes, you are right, this declaration is absolutly unnecessary, but
commenting this line out the address of v2.p in test_it0 becomes
valid( and identical to that in test_it1 ).

There's no reason from a C POV why the value above would not be valid;
nor why it should be identical to the other.
After I found where the pointer gets its invalid adress, i copied this
part to a new programm and included al the projects includes. As the
error still occures i startet to remove all includes and definitions
until i found the definition of "static char BLANK_VTRNR[2] = " ";"
changed the program behavior.

Then it probably causes whatever object you scribble on to be placed
somewhere else in memory. The error is very unlikely to be caused by
that line itself. You need to find out where that invalid pointer comes
from, not what its representation is. Somewhere in your code you are
doing something illegal to a pointer, probably some out-of-bounds
arithmetic, and that error is getting passed on.
Because i do not have any idea why this happened I asked for help here.
After I changed the Programm in the way you suggested the same error
appears:
./test_it
1. ffffff78
1. 7eff3328

Again, I don't see why this should be an error. You have to completely
different pointers, to two completely different objects. There's no
reason why they should be the same in the first place.

In the following you can see the part of the original code, which has
the described error:

This code does something completely different from what your original
example did. That called _two_ functions, and printed two different
pointers to separate objects in those separate functions. It is no
surprise that those could be different. This code seems to involve only
a single function. That's a whole other kettle of red herrings.

[ Rearranged for easier reading. ]
typedef struct sMaschStoExtern t_MaschStoExtern;
typedef t_MaschStoExtern *t_ptrMaschStoExtern;
struct sMaschStoExtern
{
char cfAttributName[ MASCHSTO_ATTRNAME_LEN + 1 ];
char cfAttributWert[ MASCHSTO_ATTRWERT_LEN + 1 ];
char cfAusgabe[ MASCHSTO_AUSGABE_LEN + 1 ];
t_ptrMaschStoExtern pNext;
};
typedef struct s_AusdatFeldbeschreibung
{
short sTyp;
int iLaenge;
void *pWert;
BOOL bFehlerhaft;
} t_AusdatFeldbeschreibung;
t_MaschStoExtern AktSatz;
t_AusdatFeldbeschreibung ExterneHinweise[ MASCHSTO_EXTERN_ANZ_FD ] =
{ /* Typ, Laenge , Pointer zur Variablen , Fehler */
{ AUSDAT_TYPE_STRING, MASCHSTO_ATTRNAME_LEN, AktSatz.cfAttributName, FALSE },

And here's the rub. In C89,
# All the expressions in an initializer for an object that has static
# storage duration or in an initializer list for an object that has
# aggregate or union type shall be constant expressions.

A struct is an aggregate type; the address of an automatic object is not
a constant expression.

This restriction is lifted for aggregates and unions in C99, btw. It's
still there for static objects, for obvious reasons.

Richard
 
C

Chris Torek

After I changed the Programm in the way you suggested the same error
appears:
./test_it
1. ffffff78
1. 7eff3328

----------/snip/--------------
#include <stdio.h>

I note there is no "#include said:
static char BLANK_VTRNR[2] = " ";

struct s1{ char c[ 81 ]; };
struct s2{ void *p; };

void test_it0( void )
{
struct s1 v1;
memset( (void*)&v1, 0, sizeof( struct s1 ) );
struct s2 v2 = { &v1.c };

Declaration "after code" (after the call to memset, without an open
brace) is a C99 feature. Apparently your compiler supports at least
this part of C99.
printf( "1. %p\n", v2.p );
/*
strcpy( v2.p, "Hallo ich schreibe mal was rein.." );
printf( "%s\n", v2.p );
*/
}

void test_it1(void)
{
struct s1 v1;
struct s2 v2= { &v1.c };
printf( "1. %p\n", v2.p );
/*
strcpy( v2.p, "Hallo ich schreibe mal was rein.." );
printf( "%s\n", v2.p );
*/
}

int main ()
{
test_it0();
test_it1();
return 0;
}

We have to do a little bit of guessing about the "%p" output in:
> ./test_it
1. ffffff78
1. 7eff3328

(because of course Standard C says nothing about it), but it appears
to be a straightforward hex-dump of the actual 32-bit address. (On
the other hand, other output you have shown suggests that the machine
has 64-bit addresses, and probably multiple compiler models such as
IL32P64 -- int-and-long are 32 bits and pointers are 64, I32LP64, and
maybe even an ILP32 model, as this output suggests.)

Assuming a conventional machine and 32-bit pointers, at least one of
those numbers is quite likely quite wrong; the two values should be
near each other, e.g., both "about" 7eff33xx or both "about" ffffffxx.
If including <string.h> does not fix the problem, then you have
probably found a compiler bug -- and you have a nice short program
to demonstrate it, which improves the chance of getting it fixed,
at least. :)
 
R

Richard Bos

t_MaschStoExtern AktSatz;
t_AusdatFeldbeschreibung ExterneHinweise[ MASCHSTO_EXTERN_ANZ_FD ] =
{ /* Typ, Laenge , Pointer zur Variablen , Fehler */
{ AUSDAT_TYPE_STRING, MASCHSTO_ATTRNAME_LEN, AktSatz.cfAttributName, FALSE },

And here's the rub. In C89,
# All the expressions in an initializer for an object that has static
# storage duration or in an initializer list for an object that has
# aggregate or union type shall be constant expressions.

A struct is an aggregate type; the address of an automatic object is not
a constant expression.

Note that I tried this in Dev-C++, which accepted it (DJGPP does not),
and it gave the same value for the two pointers (even though it didn't
have to accept the code at all). Try and see what happens if you compile
and run the following code:

#include <stdio.h>

int main()
{
typedef struct sMaschStoExtern t_MaschStoExtern;
typedef t_MaschStoExtern *t_ptrMaschStoExtern;
struct sMaschStoExtern {
char cfAttributName[ 30 ];
char cfAttributWert[ 30 ];
char cfAusgabe[ 30 ];
t_ptrMaschStoExtern pNext;
};

typedef struct s_AusdatFeldbeschreibung {
short sTyp;
int iLaenge;
void *pWert;
int bFehlerhaft;
} t_AusdatFeldbeschreibung;

t_MaschStoExtern AktSatz;

t_AusdatFeldbeschreibung ExterneHinweise[] = {
{ 6, 30, AktSatz.cfAttributName, 0 },
{ 6, 30, AktSatz.cfAttributWert, 0 },
{ 6, 30, AktSatz.cfAusgabe , 0 }
};

printf("Akt: %p\tExt: %p\n", (void *)AktSatz.cfAttributName,
(void *)ExterneHinweise[0].pWert);

getchar();
return 0;
}

If this gives two different values, or the compiler complains about it,
you'll probably just have to initialise your structs differently. If it
gives the same value for both (as it does for me), your problem seems to
be elsewhere.

Richard
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top