type casting a pointer (to a structure) to a pointer (to a different structure)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Schkhan
    New Member
    • Mar 2008
    • 2

    type casting a pointer (to a structure) to a pointer (to a different structure)

    Hi,
    I am sturggling with a peace of code mainly its about casting a pointer to one type of structure to a pointer to another type of structure.

    the confusion begins with the following line...(modifie d to highlight the actual prob)

    #define TEST_MACRO(firs t) ((struct second *) &first[1])

    /*here it would return a pointer to second, but the question is why it uses [1]
    Here in this example "first" and "second" are two different structures*/

    Then later in the code:

    void somefucntion (struct first * fptr)
    {
    struct second * sptr= TEST_MACRO(fptr );

    /*then they use sptr to access various fields in the second structure e.g */

    a_pointer= sptr->first_elemen t;

    .
    .
    .

    Now my question is that after typecasting a pointer of one type of structure to another one, how can we use that (in this case the sptr) to access its members, i mean how values are assigned to them just by typecasting one pointer to another and in this case they are completly different structures. Thanks in advance!

    Regards,
    Khan
  • Ganon11
    Recognized Expert Specialist
    • Oct 2006
    • 3651

    #2
    Are they different structs with the same basic structure? i.e.

    [CODE=cpp]struct first {
    int myInt;
    char myChar;
    double myDouble;
    string myName;
    };

    struct second {
    int myInt;
    char myChar;
    };[/CODE]

    If so, you should probably be able to access the members of second normally. Of course, this will be messed up if you use an array of second structs - in that case, you'll be changing the myDouble and myName values with every new second struct.

    I'd have to ask, though, why you have to be typecasting to different pointer types?

    Comment

    • Schkhan
      New Member
      • Mar 2008
      • 2

      #3
      Originally posted by Ganon11
      Are they different structs with the same basic structure? i.e.

      [CODE=cpp]struct first {
      int myInt;
      char myChar;
      double myDouble;
      string myName;
      };

      struct second {
      int myInt;
      char myChar;
      };[/CODE]

      If so, you should probably be able to access the members of second normally. Of course, this will be messed up if you use an array of second structs - in that case, you'll be changing the myDouble and myName values with every new second struct.

      I'd have to ask, though, why you have to be typecasting to different pointer types?
      Many thanks for your reply. Let me clarify things a little bit,
      these are two completly different structures. the initial point of confustion is in the macro,
      #define TEST_MACRO(firs t) ((struct second *) &first[1])

      it essentially returns a pointer to a structure of type "second", but why they are using an index value, i mean they could have done it like
      #define TEST_MACRO(firs t) ((struct second *) &first)

      the next point of confusion is that after we use
      void somefucntion (struct first * fptr)
      {
      struct second * sptr= TEST_MACRO(fptr );

      a_pointer= sptr->first_elemen t;



      the confusion here is that how can we access a member of "second" through sptr just by typecasting a pointer of type "first" and in this case their sizes are different. can you provide an insight into this. Thanks in advance.

      regards,
      Khan

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        A reason you might do this is if the pointer to first actually represents the handle of a piece of memory (probably allocated from the heap) which contains at least 2 structures or areas which in this case are defined differently.

        You know that the second structure appears immediately after the first structure in memory but only have the pointer to the first (because that is easy to use as a handle). This might be fairly common in an ADT

        Example
        [code=c]
        struct PublicData {
        char Name[20];
        };

        struct PrivateData {
        void *buffer;
        int buffer_type;
        }

        struct PublicData *Create(char *Name)
        {
        PublicData *ppd;

        pPublic = malloc(sizeof(s truct PublicData) + sizeof(struct PrivateData));

        if (pPublic != NULL)
        {
        strcpy(pPublic->Name, Name);

        /* Code to fill in private data */
        }

        return pPublic;
        }

        int GetSizestruct PublicData *pPublic)
        {
        int size;
        /* calculate pointer to private data from public data */
        struct PrivateData *pPrivate = (struct PrivateData *)&pPublic[1];

        /* Use pPrivate to calculate size of data */

        return size;
        }[/code]Bascially the construct uses pointer arithmatic to find the location immediately following the first structure, it knows this is the second structure so it casts the pointer to the correct type.

        I believe this is platform defined behaviour, that is you have no guarantee that casting a pointer to 1 type to a pointer to another is going to work as expected(except for TYPE * to void * and then void * to TYPE *). However it does seem to work fine on many platforms.

        Comment

        • Banfa
          Recognized Expert Expert
          • Feb 2006
          • 9067

          #5
          Originally posted by Schkhan
          #define TEST_MACRO(firs t) ((struct second *) &first[1])

          it essentially returns a pointer to a structure of type "second", but why they are using an index value, i mean they could have done it like
          #define TEST_MACRO(firs t) ((struct second *) &first)
          No they couldn't these 2 macros are not equivalent, your 2nd macro here is equivalent to

          #define TEST_MACRO(firs t) ((struct second *) &first[0])

          Arrays index from 0 remember

          Comment

          Working...