Thread: Only the last element of the array works.

  1. #1
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68

    Only the last element of the array works.

    My code has been acting odd. I made a function that layers my art resources but only the last tile of my art resource acts the way it should. My character goes behind and in front of the last tile and gets printed correctly. Strangely its really exclusive to the last tiles I print. What I need is to figure out in step by step order what going on with my code sample below and be able to layer the resources.


    Here is a small sample of my main function. This is how I do my rendering.

    Code:
    Int main (int arc, char* args[])
    {
    
    //Move class
    Move character;
    
    //Class Tile & Side Tile
    Tile *tiles [TOTAL_TILES];
    SideTile *walls [TOTAL_TILES_WALL];
    
    //Render the floor tiles first
    for (int t = 0; t < TOTAL_TILES_WALL; t++)
    {
    //Call a show function to render tiles
    tiles[t]->show();
    }
    
    for (int tz = 0; tz < TOTAL_TILES_WALL; tz++)
    {
    if (character.layer_maintance(tiles, walls)==1)
    {
    //By changing the order of the calls I print them on screen differently
    character.show();
    Character.show_attack();
    wall[tz]->show_side();
    }
    
    if (character.layer_maintance(tiles, walls)==2)
    {
    character.show();
    Character.show_attack();
    wall[tz]->show_side();
    }
    
    if (character.layer_maintance(tiles, walls)==3)
    {
    wall[tz]->show_side();
    character.show();
    Character.show_attack();
    }
    
    }
    //Finally I print to the screen with this function.
    SDL_Flip(screen)
    }
    
    
    
    
    
    }
    Last edited by LAURENT*; 10-05-2014 at 06:48 PM.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  2. #2
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    What does this function look like?

    Code:
       character.layer_maintance(tiles, walls)
    It seems like since it has access to all the elements needed to render, it would be easier to do it in that class (but maybe it wouldn't be good from a design standpoint, I don't know).

    Edit: I just noticed this code isn't contained in an outer loop, so is this like a one shot rendering or something?
    Last edited by Alpo; 10-05-2014 at 07:59 PM.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  3. #3
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    Oh I forgot about that. Yeah I typed this but there is an outer loop. The outer loop is a while statement that runs forever until a user closes the program. Its basically "while (quit == false)".

    You know what's funny. I put a break point right at the end of the for loop and "tz" was equal to 12. What really strange about this is that tz should've equal 0.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  4. #4
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by LAURENT* View Post
    Oh I forgot about that. Yeah I typed this but there is an outer loop. The outer loop is a while statement that runs forever until a user closes the program. Its basically "while (quit == false)".

    You know what's funny. I put a break point right at the end of the for loop and "tz" was equal to 12. What really strange about this is that tz should've equal 0.
    I had a horribly stupid bug in a game engine once where I had just moved all the character/ enemy classes into a vector inside a level class. The character would show up in the very first frame, and then disappear thereafter. I was sure I was rendering in the wrong order, or with the wrong blending, ect. I was so sure of this that it took nearly 2 days for me to notice I had written the character render loop using a static int!

    The lesson I learned from that, don't come to any conclusions before looking at everything first .
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  5. #5
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    Quote Originally Posted by Alpo View Post
    I had a horribly stupid bug in a game engine once where I had just moved all the character/ enemy classes into a vector inside a level class. The character would show up in the very first frame, and then disappear thereafter. I was sure I was rendering in the wrong order, or with the wrong blending, ect. I was so sure of this that it took nearly 2 days for me to notice I had written the character render loop using a static int!

    The lesson I learned from that, don't come to any conclusions before looking at everything first .
    That seems very plausible right now considering how rock solid this variable appears to be but look at the way I used it my for loop.
    TOTAL_WALL_TILE = 12

    Code:
    for (int tz = 0; tz < 12; tz++)

    I guess I'll check over the code 3 times to make sure nothing is wrong.
    Last edited by LAURENT*; 10-05-2014 at 09:27 PM.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The first problem in your code is even earlier than what Alpo has picked up.
    Quote Originally Posted by LAURENT* View Post
    Code:
    Int main (int arc, char* args[])   // I assume the uppercase I here is a typo in posting
    {
    
    //Move class
    Move character;
    
    //Class Tile & Side Tile
    Tile *tiles [TOTAL_TILES];
    SideTile *walls [TOTAL_TILES_WALL];
    
    //Render the floor tiles first
    for (int t = 0; t < TOTAL_TILES_WALL; t++)
    {
    //Call a show function to render tiles
    tiles[t]->show();
    }
    Your first problem is here. tiles is an array of uninitialised pointers. Any manner of dereferencing an unininitialised pointer - including any usage of the -> operator - gives undefined behaviour.


    Creating an array of pointers does not initialise those pointers, and does not create objects for those pointers to point at. If you want the pointers to be initialised, and to point to actual valid objects, your code needs to explicitly set that up
    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.

  7. #7
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by grumpy View Post
    Your first problem is here. tiles is an array of uninitialised pointers. Any manner of dereferencing an unininitialised pointer - including any usage of the -> operator - gives undefined behaviour.

    Creating an array of pointers does not initialise those pointers, and does not create objects for those pointers to point at. If you want the pointers to be initialised, and to point to actual valid objects, your code needs to explicitly set that up
    Oh yeah I noticed that, but since everything looked to be uninitialized I was just assuming the functions initialized the class and worked off a set of global data or something lol.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Alpo View Post
    Oh yeah I noticed that, but since everything looked to be uninitialized I was just assuming the functions initialized the class and worked off a set of global data or something lol.
    You assumed wrong. tiles[i]->show() dereferences tiles[i] (i.e. accesses whatever it points at) before calling the show() method. That is undefined behaviour. Once undefined behaviour occurs, there is no recovery, and there is nothing the show() method (or any subsequently called function for that matter) can do to recover (short of invoking their own forms of undefined behaviour - compiler specific hacks, etc). Even if the show() method initialises the object correctly, it cannot change the pointer tiles[i] which is in a different scope (within main()).
    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.

  9. #9
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    So if I move int tz out of the scope will it work then?
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  10. #10
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    Hello forums. I have figured out a work around. This is technically good enough according to the personal quotas I want to meet but I'm still very interested in a solution for the array.

    Code:
    for
    ( int t = 0; t < TOTAL_TILES; t++ ) 
    
        { 
    
            tiles[ t ]->show(); 
    
        } 
    
        
      //print the character first,
        character.show(); 
        character.show_attack();
    
    
     
    
        //print the tiles second
    for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ ) 
    
        {
            walls[ tz ]->show_side();     
        }
    
                
    
        //if this function return 2 print the character again. 
    if (character.layer_maintance(tiles,walls) == 3)
    
         {
                character.show(); 
                character.show_attack();
         }
    
            
    
        
    
        
    //Update the screen 
    
        
    if( SDL_Flip( screen ) == -1 ) 
    
        { 
    
            
    return 1; 
    
        } 
    
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by LAURENT* View Post
    So if I move int tz out of the scope will it work then?
    No, the point is that the array must be initialized before it's used. Moving a variable somewhere else does not fix the problem.

    Can't say anything about your "proposed" solution either, as it's lacking context.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by LAURENT* View Post
    Hello forums. I have figured out a work around. This is technically good enough according to the personal quotas I want to meet but I'm still very interested in a solution for the array.

    Code:
    for
    ( int t = 0; t < TOTAL_TILES; t++ ) 
    
        { 
    
            tiles[ t ]->show(); 
    
        } 
    
        
      //print the character first,
        character.show(); 
        character.show_attack();
    
    
     
    
        //print the tiles second
    for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ ) 
    
        {
            walls[ tz ]->show_side();     
        }
    
                
    
        //if this function return 2 print the character again. 
    if (character.layer_maintance(tiles,walls) == 3)
    
         {
                character.show(); 
                character.show_attack();
         }
    
            
    
        
    
        
    //Update the screen 
    
        
    if( SDL_Flip( screen ) == -1 ) 
    
        { 
    
            
    return 1; 
    
        } 
    
    My advice would be to develop a base 'Layer' type class. Then you can create subclasses with names like 'ObjectLayer' (contains vector of Players/ enemies ect), and 'TileLayer' (contains tiles).

    That way you can treat these render-able classes more agnostically. Say for instance you have an array of 'Layer' class somewhere ( declared std::vector<Layer*> m_layers ). You can simply add pointers to the different TileLayers, and ObjectLayers in the order you wish them to appear, and render/update the entire thing with a call that looks something like:

    Code:
       for( int i = 0; i < m_layers.size(); i++)
       {
          m_layers[i]->draw(); /// Let Polymorphism do it's thing
       }
    Hope any of that is helpful. Good luck!

    Edit: Initialization of Layer* objects not shown.
    Last edited by Alpo; 10-06-2014 at 11:50 AM.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Alpo View Post
    ...Say for instance you have an array of 'Layer' class somewhere ( declared std::vector<Layer*> m_layers )...
    You should declare the vector as
    std::vector<std::unique_ptr<Layer>>
    or
    std::vector<std::shared_ptr<Layer>>

    Use std::make_shared or std::make_unique (C++14 only; otherwise use new combined with a unique_ptr container) to create the objects.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    Quote Originally Posted by Alpo View Post
    My advice would be to develop a base 'Layer' type class. Then you can create subclasses with names like 'ObjectLayer' (contains vector of Players/ enemies ect), and 'TileLayer' (contains tiles).

    That way you can treat these render-able classes more agnostically. Say for instance you have an array of 'Layer' class somewhere ( declared std::vector<Layer*> m_layers ). You can simply add pointers to the different TileLayers, and ObjectLayers in the order you wish them to appear, and render/update the entire thing with a call that looks something like:

    Code:
       for( int i = 0; i < m_layers.size(); i++)
       {
          m_layers[i]->draw(); /// Let Polymorphism do it's thing
       }
    Hope any of that is helpful. Good luck!

    Edit: Initialization of Layer* objects not shown.
    To be honest I've never used a vector before. I've played around with structs but never anything serious. This project has been all about experimentation. I've added multiple sources files, classes, and even practiced inheritage.

    I'll save this for a checkers game I plan to make. I started this project wrong and I don't think I should try stuff that too unique unless it the only way.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  15. #15
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Oh man, you should totally start using vectors. They're like the bread and butter of C++.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. array of ptrs vs constant ptr to an first element of array
    By monkey_c_monkey in forum C Programming
    Replies: 5
    Last Post: 08-30-2012, 11:39 PM
  2. Removing an array in an element?
    By bluej322 in forum C Programming
    Replies: 4
    Last Post: 02-19-2011, 11:36 PM
  3. size of an array poited by array element
    By mitofik in forum C Programming
    Replies: 7
    Last Post: 12-24-2010, 12:09 AM
  4. Replies: 15
    Last Post: 09-23-2010, 02:19 PM
  5. Cannot delete last element in array
    By Simon in forum C Programming
    Replies: 10
    Last Post: 09-12-2002, 08:29 PM