Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   typecasting pointer issues (http://www.velocityreviews.com/forums/t449624-typecasting-pointer-issues.html)

PapaTodd@gmail.com 11-07-2005 11:29 PM

typecasting pointer issues
 
Greetings all,

I've been fighting with this issue all day. This code is tried and
true on other OS's, but when I compile and test on AIX 5.3 using xlC_r,
I have problems.

Here is the code snippets giving a problem:


main.cpp
---------------------------------
mySchemaType *theSchema = NULL; // declared as global

// within main()
theSchema = prepareSchemaAndFilters(some strings showing files);

pRecord = theSchema->records;
pField = pRecord->fields;
mySpecificType *tmpRecord = (mySpecificType *)pField->specific;
printf("the specific db_type = %s\n",tmpRecord->db_type);

----------------------------------
At this point, db_type is shown to be garbage. This is my problem.
Here is what prepareSchemaAndFilters looks like:

makeschema.c
----------------------------------
mySchemaType *prepareSchemaAndFilters(the file strings)
{
mySchemaType *theSchema;
// code removed for clarity, essentially items are put into theSchema
myRecordType *pRecord = theSchema->records;
myFieldType *pField = pRecord->fields;
mySpecificType *tmpRecord = (mySpecificType *)pfield->specific;
printf("the specific db_type = %s\n",tmpRecord->db_type);

return theSchema;
}
----------------------------------
Within makeschema.c, the specific db_type is output the expected value.

Here are the type definitions:
schema.h
----------------------------------
typedef struct my_record myRecordType;
typedef struct my_field myFieldType;
typedef struct my_schema mySchemaType;
typedef struct my_specific mySpecificType;

struct my_specific {
char name[256];
char db_type[256];
int db_length;
void *additional_specific;
refKey* firstRefKey;
refKey* lastRefKey;
};

struct my_field {
char* name;
char* my_name;
myFieldType* fields;
bool is_key;
bool is_binary;
bool is_single;
FilterType filter;
void* specific;
stringList* values;
myFieldType* next;
}

struct my_record {
char* name;
char* my_name;
myFieldType* fields;
FilterType filter;
void* specific;
int seqno;
myRecordType* next;
int updateNumber;
};

struct my_schema {
mesRecord* records;
void* specific;
};

-------------------------------

So, finally to the source of my problem. When I am within mes_schema.c
(linked in as a library), I can cast the void* as a specific* and get
the different values. When I am back in main.cpp, if I do this, the
values that are part of specific* print correctly.

This appears to be a pointer error, and I suspect any of the following
possibilities:
1) Even though I'm explicitely compiling under 32-bit mode, somehow the
pointers are not being handled properly.
2) Some weird translation between the .c library and the .cpp file? We
are using an extern "C" { flag for the .c files, but maybe this isn't
good enough when we compile?

As I mentioned before, on this system (AIX 5L), we are seeing this
problem. On all others (HP-UX, Win, Solaris), we don't.

Any advice would be appreciated. Tonights task is to start wading
through dbx to verify that it is an invalid pointer issue, but if I
verify that, I'm not sure what the fix is going to be.

Thanks in advance,

Todd


Alf P. Steinbach 11-07-2005 11:46 PM

Re: typecasting pointer issues
 
* PapaTodd@gmail.com:
>
> I've been fighting with this issue all day. This code is tried and
> true on other OS's, but when I compile and test on AIX 5.3 using xlC_r,
> I have problems.
>
> Here is the code snippets giving a problem:
>
>
> main.cpp
> ---------------------------------
> mySchemaType *theSchema = NULL; // declared as global


That's the first problem, and the solution is: DON'T USE GLOBAL
VARIABLES.



> // within main()
> theSchema = prepareSchemaAndFilters(some strings showing files);
>
> pRecord = theSchema->records;
> pField = pRecord->fields;
> mySpecificType *tmpRecord = (mySpecificType *)pField->specific;


That's a second problem: you're doing a reinterpret_cast using C
notation so you don't know what it is, and the solution is: USE C++
STYLE CASTS IF YOU ABSOLUTELY MUST CAST.

And the casting is a third problem, for which the solution is DON'T USE
CASTS.


> printf("the specific db_type = %s\n",tmpRecord->db_type);




> ----------------------------------
> At this point, db_type is shown to be garbage.


Not surprising; see above.


> This is my problem.
> Here is what prepareSchemaAndFilters looks like:
>
> makeschema.c
> ----------------------------------
> mySchemaType *prepareSchemaAndFilters(the file strings)
> {
> mySchemaType *theSchema;
> // code removed for clarity, essentially items are put into theSchema
> myRecordType *pRecord = theSchema->records;
> myFieldType *pField = pRecord->fields;
> mySpecificType *tmpRecord = (mySpecificType *)pfield->specific;
> printf("the specific db_type = %s\n",tmpRecord->db_type);
>
> return theSchema;
> }


You don't show enough code to diagnose the technical problem, in
particular you don't show the earlier assignment to 'pfield->specific'.

Why did you think the relevant code would not matter?

However, what you show is enough to diagnose the real problem, which is:
assembly language level coding (expressed in C or C++ doesn't matter).

[snip]
> So, finally to the source of my problem. When I am within mes_schema.c
> (linked in as a library), I can cast the void* as a specific* and get
> the different values. When I am back in main.cpp, if I do this, the
> values that are part of specific* print correctly.


?

Anyway, sound like you have a pointer pointing to deallocated storage,
nowhere in particular, or the stack.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Todd 11-08-2005 03:39 AM

Re: typecasting pointer issues
 
Alf P. Steinbach wrote:
> * PapaTodd@gmail.com:
> >
> > I've been fighting with this issue all day. This code is tried and
> > true on other OS's, but when I compile and test on AIX 5.3 using xlC_r,
> > I have problems.
> >
> > Here is the code snippets giving a problem:
> >
> >
> > main.cpp
> > ---------------------------------
> > mySchemaType *theSchema = NULL; // declared as global

>
> That's the first problem, and the solution is: DON'T USE GLOBAL
> VARIABLES.
>
>
>
> > // within main()
> > theSchema = prepareSchemaAndFilters(some strings showing files);
> >
> > pRecord = theSchema->records;
> > pField = pRecord->fields;
> > mySpecificType *tmpRecord = (mySpecificType *)pField->specific;

>
> That's a second problem: you're doing a reinterpret_cast using C
> notation so you don't know what it is, and the solution is: USE C++
> STYLE CASTS IF YOU ABSOLUTELY MUST CAST.
>
> And the casting is a third problem, for which the solution is DON'T USE
> CASTS.
>
>
> > printf("the specific db_type = %s\n",tmpRecord->db_type);

>
>
>
> > ----------------------------------
> > At this point, db_type is shown to be garbage.

>
> Not surprising; see above.
>
>
> > This is my problem.
> > Here is what prepareSchemaAndFilters looks like:
> >
> > makeschema.c
> > ----------------------------------
> > mySchemaType *prepareSchemaAndFilters(the file strings)
> > {
> > mySchemaType *theSchema;
> > // code removed for clarity, essentially items are put into theSchema
> > myRecordType *pRecord = theSchema->records;
> > myFieldType *pField = pRecord->fields;
> > mySpecificType *tmpRecord = (mySpecificType *)pfield->specific;
> > printf("the specific db_type = %s\n",tmpRecord->db_type);
> >
> > return theSchema;
> > }

>
> You don't show enough code to diagnose the technical problem, in
> particular you don't show the earlier assignment to 'pfield->specific'.
>
> Why did you think the relevant code would not matter?
>
> However, what you show is enough to diagnose the real problem, which is:
> assembly language level coding (expressed in C or C++ doesn't matter).
>
> [snip]
> > So, finally to the source of my problem. When I am within mes_schema.c
> > (linked in as a library), I can cast the void* as a specific* and get
> > the different values. When I am back in main.cpp, if I do this, the
> > values that are part of specific* print correctly.

>
> ?
>
> Anyway, sound like you have a pointer pointing to deallocated storage,
> nowhere in particular, or the stack.
>
> --
> A: Because it messes up the order in which people normally read text.
> Q: Why is it such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?


My general excuse for some of the sloppy coding is that it is
inherited. Not that I'm a great programmer, but... anyway, moving
forward.

First test: change the returned variable theSchema to a local. Didn't
help.
Second test: change the void* to specific* in the structure
declaration. Didn't help.

So I'm beginning to think that the problem is that the original setting
of the values isn't being handled well, and it is just luck that it
worked on all of our other products/platform combinations.

I don't want this to turn into a "fix my program one step at a time for
me", so I'm going to spend another day debugging it tomorrow. The code
that initially sets the values that are read from the file appear to be
correct at first glance, doing things such as allocating memory, then
setting the values, or duplicating the strings via an inline function.

Thanks for your help,

Todd


Alf P. Steinbach 11-08-2005 03:46 AM

Re: typecasting pointer issues
 
* Todd:
>
> First test: change the returned variable theSchema to a local. Didn't
> help.
> Second test: change the void* to specific* in the structure
> declaration. Didn't help.


Did you also remove _all_ the casts?

They can be difficult to spot.

Hiding themselves away in innocent-looking code, like gremlins... ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

savagesmc 11-08-2005 01:07 PM

Re: typecasting pointer issues
 
In prepareSchemaAndFilters, is there some code that allocates some
memory for a concrete type into the void* (pfield->specific) and loads
values into it? Also, you should show the code that allocates the
mySchema in general.

Need more sample code.


Kaz Kylheku 11-08-2005 07:12 PM

Re: typecasting pointer issues
 
Alf P. Steinbach wrote:
> > pRecord = theSchema->records;
> > pField = pRecord->fields;
> > mySpecificType *tmpRecord = (mySpecificType *)pField->specific;

>
> That's a second problem: you're doing a reinterpret_cast using C
> notation so you don't know what it is, and the solution is: USE C++
> STYLE CASTS IF YOU ABSOLUTELY MUST CAST.


No, you want static_cast here. A void * pointer is being used as a
generic handle on some variant data.

The best way to handle that is to take advantage of the implicit
conversion /to/ the void *, and use static_cast to do the reverse of
that implicit conversion.

Yes, try to use a C++ cast but don't choose a stronger cast, or
combination of casts, than what the traditional notation would
choose!!!

:)


Alf P. Steinbach 11-08-2005 07:32 PM

Re: typecasting pointer issues
 
* Kaz Kylheku:
> Alf P. Steinbach wrote:
> > > pRecord = theSchema->records;
> > > pField = pRecord->fields;
> > > mySpecificType *tmpRecord = (mySpecificType *)pField->specific;

> >
> > That's a second problem: you're doing a reinterpret_cast using C
> > notation so you don't know what it is, and the solution is: USE C++
> > STYLE CASTS IF YOU ABSOLUTELY MUST CAST.

>
> No, you want static_cast here.


A static cast is a C++ style cast, so what does the "no" refer to?

If the conversion to and back from void* is not a reinterpret_cast in
disguise, then the void* isn't needed, and is meaningless.

Therefore, I think the void* is a reinterpret_cast in disguise.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Greg Comeau 11-08-2005 08:53 PM

Re: typecasting pointer issues
 
In article <4370fb1e.1923812453@news.individual.net>,
Alf P. Steinbach <alfps@start.no> wrote:
>* Kaz Kylheku:
>> Alf P. Steinbach wrote:
>> > > pRecord = theSchema->records;
>> > > pField = pRecord->fields;
>> > > mySpecificType *tmpRecord = (mySpecificType *)pField->specific;
>> >
>> > That's a second problem: you're doing a reinterpret_cast using C
>> > notation so you don't know what it is, and the solution is: USE C++
>> > STYLE CASTS IF YOU ABSOLUTELY MUST CAST.

>>
>> No, you want static_cast here.

>
>A static cast is a C++ style cast, so what does the "no" refer to?


He means to use static_cast in this case over reinterpret_cast.

>If the conversion to and back from void* is not a reinterpret_cast in
>disguise, then the void* isn't needed, and is meaningless.
>
>Therefore, I think the void* is a reinterpret_cast in disguise.


This one's a funny one. In cases where you're converting to
a void * and back, I would say that static_cast is preferred.
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

savagesmc 11-09-2005 12:16 AM

Re: typecasting pointer issues
 
I thought the key comment in the original post was that the casting
worked from main, but not in the function just before the return.
Changing the style of casting doesn't seem like it would have anything
to do with that type of observed behavior. It seems to me that there
is more of a pointer problem somewhere, which is why I suggested it
might be nice to see the other parts of the hcode that go with that
example.

Unless one of you more experienced c++ guys can explain how doing a
cast in a function can give a different answer than doing the same
exact cast in the scope where the function was called.

Steve


Old Wolf 11-09-2005 12:47 AM

Re: typecasting pointer issues
 
PapaTodd@gmail.com wrote:

> Greetings all,
>
> I've been fighting with this issue all day. This code is tried
> and true on other OS's, but when I compile and test on AIX 5.3
> using xlC_r, I have problems.
>
> Here is the code snippets giving a problem:
> mySpecificType *tmpRecord = (mySpecificType *)pField->specific;


Perhaps pField->specific is not correctly aligned for a
pointer to mySpecificType.

Can you post the code where pField->specific is given its value?

For debugging, you could try printing out the void pointer and
then printing out the casted pointer, that might give you a clue
as to what happened.



All times are GMT. The time now is 07:02 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.