Thread: Vector Question

  1. #46
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Sorry, I forgot to change that. My example Obsolete was a function, so I used the parentheses. Your Obsolete is a bool variable, so you should remove the parentheses:

    if ((*currentLaser)->Obsolete)

    The reason ++i is preferred over i++ is that in general, when you use i++, the code must make a copy of i, then increment it, then return the copy. Even if you don't use the returned value, the code that figures it out might still be run. When you use ++i, i is incremented first, and then returned without a copy being made. Since you are ignoring the return value, you don't care what is returned, the pre-incremented value or the post-incremented value. Since you don't care, it is better to go with the one that won't require an unnecessary copy. It is possible that the extra copy is optimized away, but I wouldn't count on it and there is no reason to since there is really no difference to you in writing one or the other. This isn't a big deal, just another suggested good habit.

  2. #47
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>Wow...I must have reached some record for most help needed! lol.
    No, nobody has surpassed me yet

    Funny, because I think I remember asking both those questions above before... heh... I'm still the n00b m4st4!
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #48
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Quote Originally Posted by Hunter2
    No, nobody has surpassed me yet
    Damn! O well....

    Alright, I've been trying that code, and frankly, I feel really stupid and frustrated now! Every time, at this line

    Code:
    if ((*currentLaser)->Obsolete)
    if raises an exception. Any help would be great, as this project is due real soo!

    Cheers

    DW

  4. #49
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Since you are holding pointers in your vector, one possible reason you are getting an exception on that line is if the pointer stored in the vector is invalid - meaning it is null or has already been deleted or was never initialized. That is one of the reasons I kept advising you to not use pointers.

    Another note, since you are holding pointers in your vector, make sure you are deleting the memory correctly. In my example Erase function, I did not free any memory because my original example held objects instead of pointers. The modified example must be updated to delete the memory at (*currentLaser) before erasing it from the list, or else you will have a memory leak.

  5. #50
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    [QUOTE=jlou]Since you are holding pointers in your vector, one possible reason you are getting an exception on that line is if the pointer stored in the vector is invalid - meaning it is null or has already been deleted or was never initialized. That is one of the reasons I kept advising you to not use pointers. QUOTE]

    Ah...well...to late now I guess. How do I test if the vector is null? I've tried if(laserVect.empty()) then ...... but nothing really happens. It doesn't seem to want to work. Any ideas? thx again

  6. #51
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    You want to test if the pointer value held at the position represented by the iterator is null. Here is one example in red (make sure you adapt it appropriately to your needs). I also added an example of deleting memory in blue. This code removes and deletes the memory of Obsolete User_Lasers AND removes null pointers.
    Code:
    void EraseObsoleteLasers(std::vector<User_Laser*>& laserList)
    {
        std::vector<User_Laser*>::iterator currentLaser = laserList.begin();
        while (currentLaser != laserList.end())
        {
            if ((*currentLaser) == 0 || (*currentLaser)->Obsolete)
            {
                User_Laser* laserToDelete = (*currentLaser);
                currentLaser = laserList.erase(currentLaser);
                delete laserToDelete;
            }
            else
            {
                ++currentLaser;
            }
        }
    }
    Last edited by jlou; 06-08-2004 at 12:09 PM.

  7. #52
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Quote Originally Posted by jlou
    You want to test if the pointer value held at the position represented by the iterator is null. Here is one example in red (make sure you adapt it appropriately to your needs). I also added an example of deleting memory in blue. This code removes and deletes the memory of Obsolete User_Lasers AND removes null pointers.
    Code:
    void EraseObsoleteLasers(std::vector<User_Laser*>& laserList)
    {
        std::vector<User_Laser*>::iterator currentLaser = laserList.begin();
        while (currentLaser != laserList.end())
        {
            if ((*currentLaser) == 0 || (*currentLaser)->Obsolete)
            {
                User_Laser* laserToDelete = (*currentLaser);
                currentLaser = laserList.erase(currentLaser);
                delete laserToDelete;
            }
            else
            {
                ++currentLaser;
            }
        }
    }
    Well.. I tired this word for word, and still the same problem.

    So...I experimented a bit.

    I tried with the for loops again. Exception. Alright....I tried setting "temp = laser.size()" and the size of a just created laser, well apparently varies between -600002 and 3965?!!?!
    Okay I said, lets make the loop counter (b =) to temp. and it works. Not very well, because I must be doing somthing wrong with the size, because you have to make, ~100 lasers before they start to show, but at least it works. Every Vector sizer(eg: temp) is different. And only one starts at 0. So i'm assuming that this isn't normal/right aka: whats causing my problems. I also tried testing for the laser.empty() property, and that didn't really work. Soo....the point to this ramble is, any idea why this is so whacked? Because when I go currentLaser-> , the auto complete thingy pops up, but not when I do, (*currentLaser)->.......soo......any help would be very much appreciated, because, I quite frankly, have no idea what i'm doing when it comes to vectors( and quite possibly, c++! )

    Cheers

  8. #53
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    The best thing I can say is to post your current code.

    I have no idea why you are getting weird sizes, but earlier when you had similar problems you said you fixed it. Maybe you made the same mistake again? Post what you have so that we can see if you are implementing these suggestions correctly.

  9. #54
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Ah, I *thought* I fixed it! Turns out the others were still wierd. I"ll post the code, but be warned, its a lot of code! I"ll double post the code below

  10. #55
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Main game loop
    Code:
    void __fastcall TForm1::GameLoop(TObject*, bool &done)
    {
    int b,temp;
    
    //checks if you've killed everything
    if (dead_count == 21)
    {
            Application->MessageBoxA("You won!","Well done, you stopped the invasion", MB_OK);
            Application->Terminate();
    }
    
       //Key presses are acted upon here
      if (keys.right == true)
        {
           User->MoveRight(); //right key pressed, move right
        }
    
      if (keys.left == true)
        {
           User->MoveLeft();  //left key pressed, move left
        }
    
      if (keys.up == true)
      {
            User->MoveUp(); //up key pressed. move up
      }
    
      if (keys.down == true)
      {
          User->MoveDown(); // down key pressed. move down
      }
    
      // fires a regular laser shot
      if (keys.laser == true)
      {
       //dynamicly allocates memory on the heap; User(the ship) is passed to the constructor
       //so the x1 && y1 coords are the same as the users
            laser.push_back(new User_Laser(User));
    
            //keys.laser = false; //un-presses the space bar so we can't have insane firing speeds =)
      }
    
      // fires a regular missile shot
      if (keys.missile == true)
      {
         //dynamicly allocates memory on the heap; User(the ship) is passed to the constructor
       //so the x1 && y1 coords are the same as the users
            missile.push_back(new User_missile(User));
    
            keys.missile = false;//un-presses the control key so we can't have insane firing speeds =)
      }
    
    
    
    
    //deletes any unused lasers, then moves the rest
    EraseObsoleteLasers(laser,Baddy);
    EraseObsoleteMissiles(missile, Baddy);
    
    
    
    //draws to the form. See the "Draw" file for further info
    Draw(BackBuffer, User, Baddy, ClientRect, BackGround, laser, missile, Health, bdy_laser, bdyDraw, FirstMissile , FirstLaser);
    
    done = false;
    
    }
    functions in header file,

    Code:
    #include <vector.h>
    #include "fire.h"
    #include "Unit1.h"
    
    using namespace std;
    
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    
    void EraseObsoleteLasers(std::vector<User_Laser*>& laserVect, Enemy *Baddy[3][7])
    {
        std::vector<User_Laser*>::iterator currentLaser = laserVect.begin();
        int b;
    
         while (currentLaser < laserVect.end())
         {
                if ((*currentLaser) == 0 || (*currentLaser)->Obsolete)
            {
                User_Laser* laserToDelete = (*currentLaser);
                currentLaser = laserVect.erase(currentLaser);
                delete laserToDelete;
            }
            else
            {
                    ++b;
                    (*currentLaser)->regShot();
                    (*currentLaser)->Collision(Baddy, laserVect, b);       //check for collision between the laser and *a* baddy
                     ++currentLaser;
            }
    
        }
    }
    
    
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    
    void EraseObsoleteMissiles(std::vector<User_missile*>& missileVect, Enemy *Baddy[3][7])
    {
        std::vector<User_missile*>::iterator currentMissile = missileVect.begin();
        int b;
        while (currentMissile != missileVect.end())
        {
            if ((*currentMissile)->Obsolete)
                currentMissile = missileVect.erase(currentMissile);
            else
            {
                    ++b;
                    (*currentMissile)->regShot();
                    
                     //check for collision between the laser and *a* baddy
                    (*currentMissile)->Collision(Baddy, missileVect, b);       
                     ++currentMissile;
            }
        }
    }
    Last edited by Death_Wraith; 06-08-2004 at 06:02 PM.

  11. #56
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Hmmm, you have #include<vector.h> at the top of your second piece of code, but then you use the STL vector which is in <vector> without the ".h". Are you including the correct headers?

    I'm not all that familiar with the specifics of C++ Builder, maybe it has a weird implementation that is causing your code to go haywire.

    Is the problem still an exception at this line?
    Code:
    if ((*currentLaser)->Obsolete)

  12. #57
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Yup, same line. About the headers, I wasn't sure what too use. A book said <vector.h> You guys were says this std namespace, and I wasn't sure what I needed, so I included both! Is this bad? Also, does the code look okay?

    Cheers


    Edit: Well, playing around with the code, i set laser.clear(); on the initialization, and low and behold it works! strange....regardless it works, needs some work tho.... funny stuff... thanks for all the help! Also, the .h thing, which do i need?

    Cheers
    Last edited by Death_Wraith; 06-08-2004 at 09:14 PM.

  13. #58
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    A book said <vector.h>
    You should use the new header style, ie:
    Code:
    #include <vector>
    using namespace std;
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  14. #59
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    I think <vector.h> is specific to Borland's libraries, and is a completely different library (not just the old style). The STL vector is in <vector>, which is what you need for what we've been talking about.

    Strange about needing the clear(), I don't know why it wouldn't start out initialized empty properly, maybe it depends on how you declared it globally. Glad it works though.

  15. #60
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Thx! Ya its deffinatly strange, although, i've come to expect that from c++. It's strange though, running all that code (shoot, collision, move lasers, delet obsolete laser) seems pretty slow. And its not like its that much code either!....Very strange...


    CHeers, and thanks for the help

    DW

Popular pages Recent additions subscribe to a feed