Thread: Can a pointer point to different data structure?

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    163

    Can a pointer point to different data structure?

    I got a tree whose node is the structure below

    Code:
    struct nodeStruct {
      struct nodeStruct *sibling;
      struct nodeStruct *child;
      unsigned int pos;  //pos of the first char in the string
    };
    Is it possible that the *child pointer can point to another type of structure beside nodeStruct?

    Because for my implementation, I need the *child pointer to be able to point to nodeStruct, or point to other types of structure.

    Thanks for your help!

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    You can use a void* that can point to any data type. However to do anything useful with it you'll have to cast it to a data type before you use it.

    IMO based off of the little you post, I would say a rework of the design is the better solution.

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    163
    Quote Originally Posted by Thantos
    IMO based off of the little you post, I would say a rework of the design is the better solution.
    Thanks for your help! I'm now reading on void pointer

    I'm sorry, I don't quite get what you mean by IMO?

    I read somewhere that cast operator can used to convert the pointer type.

    Does it work this way? For e.g.,
    Code:
    int *num;
    char *str;
    
    num = (char) str;
    Last edited by franziss; 09-03-2005 at 01:37 AM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    IMO is shorthand for "In My Opinion".

    Your example isn't quite right;

    Try
    Code:
    #include <string.h>
    #include <stdlib.h>
    int main()
    {
        void *memory;
       char *char_memory;
       double *object;
    
       memory = malloc(sizeof(double));
       char_memory = (char *)memory;    /* This cast is optional in C but mandatory in C++ */
        object= (double *)char_memory;  /*  This cast is mandatory in this example */
    
       strcpy(char_memory, "Hello");   /* Would result in undefined behaviour if sizeof(double) <= 6 */
    
       *object = 2.0;
       (*((double *)char_memory)) = 2.0;   /*  Same effect as preceding line */
       (*((double *)memory)) = 2.0;           /*  Same effect as preceding line */
       
    }

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > Is it possible that the *child pointer can point to another type of structure beside
    > nodeStruct?
    You could, but how would you tell the difference between the end of the tree and what it is you want to store?

    Perhaps you want
    Code:
    struct nodeStruct {
      struct nodeStruct *sibling;
      struct nodeStruct *child;
      void *someDataPtr;  // something else you want to store
      unsigned int pos;  //pos of the first char in the string
    };
    Indiscriminate casting between pointers looks bad, and will almost certainly lead to grief at some point.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    163
    Quote Originally Posted by Salem
    > Is it possible that the *child pointer can point to another type of structure beside
    > nodeStruct?
    You could, but how would you tell the difference between the end of the tree and what it is you want to store?
    Pardon me for leaving out the details. My tree design works this way:
    The leaf of the tree has the similar structure as the non-leaf of the tree, except that it does not contain the *child pointer.

    I leave out the *child pointer in leaf node to save space for the tree.

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    The added complexity of the code will cause more bloat then having the child pointers.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > I leave out the *child pointer in leaf node to save space for the tree.
    Premature optimisation is the root of all evil.
    I mean, every 1K nodes in your tree is only 4K of space. Given any reasonable amount of information you want to store in a leaf, this will seem like small change.
    Unless there's something else you're not telling us like it's a memory constrained embedded system.

    Making it work at all is the hardest thing to do, without the added complication of "optimisation" at the same time. When it's finished and tested, and determined that there is a need for optimisation, then you can optimise safe in the knowledge that you've got something which works, and something which you can compare against, both in terms of results (are they still the same) and by how much you managed to "improve" things.

    If you really want "the best of both worlds", then try this
    Code:
    struct nodeStruct {
      struct nodeStruct *sibling;
      union {
        struct nodeStruct *child;
        struct dataStruct *data;
      } v;
      unsigned int pos;  //pos of the first char in the string
    };              
    
    // then things like
    foo->v.child = nextnode;
    foo->v.data = mydata;
    You can assign the right thing to the right pointer without any messy void* pointers or casting, which is a bonus.

    But you need something which accurately tells you which member of the union you're supposed to be using (which will take up more memory, so all in all you don't win anything over my original suggestion).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Dec 2004
    Posts
    163
    Salem, your suggestion is great, just what I wanted. Thanks!

    Since

    struct nodeStruct *child;
    struct dataStruct *data;

    both *child and *data are pointers, they both occupy 32bits right?

    And since they are pointers, I guess I do not need any overhead to check if union v is pointing to a nodeStruct or dataStruct? Because both of them are nodes in the tree and the info they are storing is in unsigned int pos

    I had a program running, now is the optimization part... =)

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    >I guess I do not need any overhead to check if union v is
    >pointing to a nodeStruct or dataStruct?
    You should - storing one pointer type doesn't necessarily mean that the other pointer is either meaningful or valid. If you store a dataPtr, then you should only access it as a dataPtr.

    Not every machine has pointers which are uniformly the same size or the same interpretation.
    http://www.eskimo.com/~scs/C-faq/q5.17.html
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  3. Bitmasking Problem
    By mike_g in forum C++ Programming
    Replies: 13
    Last Post: 11-08-2007, 12:24 AM
  4. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  5. File Database & Data Structure :: C++
    By kuphryn in forum C++ Programming
    Replies: 0
    Last Post: 02-24-2002, 11:47 AM