Thread: Passing pointers through multiple funcs and maintaining changes made in those funcs.

  1. #1
    Feversaint
    Guest

    Passing pointers through multiple funcs and maintaining changes made in those funcs.

    First off I just want to point out that I'm fairly new to C. I've done a bit of playing around with pointers and have (mostly) successfully built a linked list that works fine. The issue I'm having now is I'm trying to divide up the initialization portion of a game I'm working on into multiple functions called from inside an Initialize() function. It's starting to get real ugly quickly as I add pointers to try and maintain changes so the values are actually initialized when I get past Initialize().

    From my understanding to change the address that a pointer points to you need to pass in a pointer to that pointer. I've tried that and it works fine if I change said address after only going one function deep. But when I try to pass this to another function, I have no idea as to what I should do both to pass it as a parameter and use it inside the next function (should I or should I not dereference it, if so how many times, what syntax should I use for this, etc.).

    Right now I'm getting a compile error:
    Code:
    mylib/game.c: In function `LoadLayers':
    mylib/game.c:146: error: request for member `object' in something not a structure or union
    I'm not sure if I'm just not dereferencing it right or what (I've tried just one *, using ->object, etc.). Help is much appreciated!

    This is what I have so far (just out of the affected functions).

    Code:
    /* From right before my primary game loop */
    
      /* --DATA DECLARATIONS-- */
      GameCharacter *player;
      LinkedList_AA *artBank;
      LinkedList_GO *layers;
      /* END DATA DECLARATIONS */
      
      layers = NULL;
      artBank = NULL;
      player = NULL;
      
      Initialize(&player, &artBank, &layers);
    
      if (player == NULL)
      {
        printf("\nPLAYER IS NULL!");
      }
      if (artBank == NULL)
      {
        printf("\nARTBANK IS NULL!");
      }
      
      if (layers == NULL)
      {
        printf("\nLAYERS IS NULL!");
      }
    Code:
    /* Initialization function definitions */
    void Initialize(GameCharacter **player, 
      LinkedList_AA **artBank, LinkedList_GO **layers)
    { 
      *artBank = InitializeList_LL_AA();  
      
      LoadArtBank(*artBank);
      
      
      *player = LoadGameCharacter("assets/objectdata/player.txt", 
        *artBank, EmptyVector2D(), "player");
      
      LoadLayers(layers, player);
     
      printf("\n\nLoad successful!\n\n\n");
    }
    
    void LoadArtBank(LinkedList_AA *artBank)
    {
      ArtAsset *testAsset;
      testAsset = LoadArtAsset("assets/art/test.txt");
    
      AddNode_LL_AA(artBank, testAsset);
    }
    
    void LoadLayers(LinkedList_GO** layers, GameCharacter** player)
    {
      int numLayers;
      numLayers = 3;
      
      *layers = InitializeListArray_LL_GO(numLayers);
    
      /* Right here is the line that's giving me grief 
          - no matter how I deference it I get the compile
          error listed below */
      AddNode_LL_GO(layers[2], **player.object); 
    }
    Code:
    /* From my linked list library */
    LinkedList_GO* InitializeListArray_LL_GO(int numLists)
    {
      LinkedList_GO *newLists;
      int i;
     
      newLists = malloc(numLists * sizeof(LinkedList_GO));
      
      for(i = 0; i < numLists; i++)
      {
        newLists[i].current = NULL;
        newLists[i].start = NULL;
      }
      
      return newLists;
    }
    
    /* Function prototype - I don't believe the inner workings
      are important for solving this issue */
    bool AddNode_LL_GO(LinkedList_GO *list, GameObject *newData);
    Code:
    /* Game character definition */
    typedef struct GameCharacter
    {
      Vector2D velocity;
      /* This is what I'm trying to access */
      GameObject object;  
    } GameCharacter;
    To clarify a few things:
    ----------------------
    - I want layers to be an array of linked lists - so I can call layers based on their index (i.e. layer[0] = layer 0)
    - GO stands for GameObject, AA stands for ArtAsset (both structs I created and am using)

  2. #2
    Feversaint
    Guest
    Shoot - noticed it right after I posted but I should have changed the title slightly. I was originally having a slightly different issue (where layers was coming back as NULL) but am now having the compile time issue. Sorry bout that...

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    C Operator Precedence Table

    . happens before *

    Try: (**foo).object

    Of course at that point, you will be passing an actual object, not a pointer to it, so any changes you make in that function won't affect the item you are passing once the function returns. (Which may be fine, I'm just clarifying.)


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    quzah's solution will stop the particular compiler error you are getting, but give a different one.

    Quote Originally Posted by Feversaint View Post
    Right now I'm getting a compile error:
    Code:
    mylib/game.c: In function `LoadLayers':
    mylib/game.c:146: error: request for member `object' in something not a structure or union
    I'm not sure if I'm just not dereferencing it right or what (I've tried just one *, using ->object, etc.). Help is much appreciated!
    The offending line, which you highlighted, is
    Code:
    AddNode_LL_GO(layers[2], **player.object);
    player is of type GameCharacter ** (pointer to pointer to GameCharacter).

    The member named object in GameCharacter is of type GameObject.

    The second argument of AddNode_LL_GO() needs to be a pointer to a GameObject.

    To work backward, *player will be a pointer to a GameCharacter. It's member named object is accessed (by reference) using (*player)->object (which is equivalent to (**player).object that quzah suggested you try). However, AddNode_LL_GO() requires a pointer, not a reference, to that object. So the offending line needs to be
    Code:
    AddNode_LL_GO(layers[2], &((*player)->object));
    or (equivalently)
    Code:
    AddNode_LL_GO(layers[2], &((**player).object));
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Feversaint
    Guest
    &(**foo).object seems to work for what I need (passing the address of object in so it can be pointed to by a node).

    (Node:
    Code:
    typedef struct Node_LL_GO
    {
      struct Node_LL_GO *next;
      GameObject *data;
    } Node_LL_GO;
    )

    It seems as though my array of LinkedLists is the issue now. My linked list is coming back initialized, but it does not remember any of the data fed into it (start and current are both NULL). I'm assuming the issue is with where I pass it into AddNode_LL_GO as I had it working when I passed it in one level up earlier. Any advice? (and thanks a ton for the help so far)

    Reminder:
    Code:
    void LoadLayers(LinkedList_GO** layers, GameCharacter** player)
    {
      int numLayers;
     
      numLayers = 3;
     
      *layers = InitializeListArray_LL_GO(numLayers);
      
      printf("\nPlayer object address: %p", (void *)&(**player).object);
      
      AddNode_LL_GO(layers[2], &(**player).object);
    }
    Edit: I actually posted this before I saw your advice grumpy - I think I'll go with the &(*player)->object - I'm still having the issue described above though
    Last edited by Feversaint; 10-02-2011 at 07:03 PM.

  6. #6
    Feversaint
    Guest
    I may have found the issue. I wanted LinkedList_GO *layers to be an array of pointers to linked lists, but instead it is just an array of linked lists. I'm going to change that and see how it goes. If I still have issues I'll post - otherwise thanks so much for the help!

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    All you should need is an array of linked lists. Then pass the address of one of those buckets:
    Code:
    void foo( struct node **bucket )
    {
        if( *bucket == NULL )
        {
            *bucket = newnode();
        }
        ... do stuff ...
    }
    
    struct node *buckets[ X ] = { NULL, };
    ...
    foo( &bucket[ 3 ] );
    You make an array of pointers to lists, and pass the individual list you want to fill or work with.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Writing to an int array made with pointers
    By n00b19 in forum C Programming
    Replies: 3
    Last Post: 04-11-2010, 10:52 AM
  2. funcs with same names - in base and derived classes
    By manav in forum C++ Programming
    Replies: 20
    Last Post: 11-30-2007, 04:54 AM
  3. Expression Manipulator v0.4 (bugs fixed, derivatives work with trig funcs)
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 06-08-2003, 08:10 AM
  4. Help w/inheritance and virtual funcs PLEASE!!!
    By cpp4ever in forum C++ Programming
    Replies: 3
    Last Post: 10-20-2001, 08:31 AM
  5. STL String and member funcs
    By Nix Phoeni in forum C++ Programming
    Replies: 3
    Last Post: 09-16-2001, 03:23 PM