typecasting pointer issues

Discussion in 'C++' started by PapaTodd@gmail.com, Nov 7, 2005.

  1. Guest

    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
    , Nov 7, 2005
    #1
    1. Advertising

  2. * :
    >
    > 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?
    Alf P. Steinbach, Nov 7, 2005
    #2
    1. Advertising

  3. Todd Guest

    Alf P. Steinbach wrote:
    > * :
    > >
    > > 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
    Todd, Nov 8, 2005
    #3
  4. * 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?
    Alf P. Steinbach, Nov 8, 2005
    #4
  5. savagesmc Guest

    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.
    savagesmc, Nov 8, 2005
    #5
  6. Kaz Kylheku Guest

    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!!!

    :)
    Kaz Kylheku, Nov 8, 2005
    #6
  7. * 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?
    Alf P. Steinbach, Nov 8, 2005
    #7
  8. Greg Comeau Guest

    In article <>,
    Alf P. Steinbach <> 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?
    Greg Comeau, Nov 8, 2005
    #8
  9. savagesmc Guest

    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
    savagesmc, Nov 9, 2005
    #9
  10. Old Wolf Guest

    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.
    Old Wolf, Nov 9, 2005
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. venkatesh
    Replies:
    1
    Views:
    8,118
    lallous
    Dec 6, 2003
  2. Robert Street

    Advanced pointer typecasting

    Robert Street, Feb 20, 2004, in forum: C++
    Replies:
    3
    Views:
    6,936
    Robert Street
    Feb 21, 2004
  3. Arun Prasath
    Replies:
    2
    Views:
    337
    Peter Shaggy Haywood
    Nov 26, 2003
  4. dis
    Replies:
    2
    Views:
    1,458
    Eric Sosman
    Jun 11, 2004
  5. Abhishek
    Replies:
    16
    Views:
    828
    Jordan Abel
    Jan 26, 2006
Loading...

Share This Page