Operating System - HP-UX
1751725 Members
5425 Online
108781 Solutions
New Discussion юеВ

Re: invalid pointer address

 
SOLVED
Go to solution
FrankAtWork
Occasional Contributor

invalid pointer address

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/---------------
7 REPLIES 7
A. Clay Stephenson
Acclaimed Contributor

Re: invalid pointer address

The one thing I notice is that you are not quite playing by the rules -- if this is C as opposed to C++. In C, variable declarations are only allowed at the top of a given block before any executable statements. Your memset() comes between variable declarations in one of your functions. C++ relaxes this rule and variable declarations can go anywhere with a block. Now, a C compiler should catch this but ...
If it ain't broke, I can fix that.
Stephen Keane
Honored Contributor

Re: invalid pointer address

I don't see what relevnce the declaration

static char BLANK_VTRNR[2] = " ";

has to the problem.

For printing the address of a pointer, I would normally use %p not %lx.

printf( "1. %p\n", v2.p );

Also, prototype of memset should be

void *memset(void *s, int c, size_t n)

In test_it1() you are printing the contents of a (void *) pointing to an address in uninitialised memory. I suspect the gcc compiler is initialising the memory for you which is why you aren't getting the error with the gcc compiler.

Thus your program should read:

extern void *memset(void *s, int c, size_t n);

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", (char *) v2.p );
}

void test_it1(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", (char *) v2.p );
}

int main ()
{
test_it0();
test_it1();

return(0);
}




FrankAtWork
Occasional Contributor

Re: invalid pointer address

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

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 bFehlerhaft = 0 ( according to definition of FALSE )

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

Even the hint that the memset instruction before the declation of struct s2 v2 = { &v1.c }; in test_it0 is not c-compliant does not help very much as this "error" is not in the original code
Stephen Keane
Honored Contributor

Re: invalid pointer address

Try :

void test_it0( void )
{
struct s1 v1;
struct s2 v2;

v2.p = (void *) &v1.c;

printf( "1. %p\n", v2.p );
}

and similar for test_it1. This way you are not initialising v2.p in an automatic
aggregate way. Might be that your aCC compiler can't deal with it.

Also,

strcpy( (char *)v2.p, "Hallo ich schreibe mal was rein.." );

I can't reproduce your problem, as I don't have an aCC compiler, only
gcc, which as you say works.
A. Clay Stephenson
Acclaimed Contributor
Solution

Re: invalid pointer address

I just compiled and executed your snippet on using HP ANSI/C B.11.11.10 and all was well. The syntax was too bad to compile using aCC but this does suggest that if you upgrade to a later version of HP ANSI/C compiler than your 11.11.04 version then you will be fine.
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: invalid pointer address

I would still upgrade to a later version of ANSI/C but there is a B.11.11.04 ANSI/C patch (PHSS_26792) which addresses a memset problem that looks exactly like yours.
If it ain't broke, I can fix that.
Dennis Handly
Acclaimed Contributor

Re: invalid pointer address

>if this is C as opposed to C++. In C, variable declarations are only allowed at the top of a given block before any executable statements.

 

Both C++ and C99 allow declarations after executable statements.