• Advertisement
Sign in to follow this  

C++ std::vector crashes with every function

Recommended Posts

Hi,

I've started to make a Flappy Bird clone just for practice, and getting back to making games after a little pause. Now I've just finished implementing a Pillar class and an ObstacleManager class, that generate, move, and delete pillars when they're out of the screen. In the ObstacleManager I store a vector of Pillar* objects, and my problem is that if I call any function of this vector, my program crashes. My code is using push_back(), empty(), front(), back(), begin(), erase(), size() and clear(), I've tried all of them individually and my program crashed. There must be something wrong with my code but I cant figure out whats the problem. I'm using vectors in other parts of the code too, and all of them works without problem. This vector of Pillar* objects always crashes but only if I call a function.

Has someone met this problem before? What could be the problem?

Share this post


Link to post
Share on other sites
Advertisement
1 hour ago, Robin04 said:

What could be the problem?

Most likely you have corrupted memory so vector<> became garbage and everything you do starts to cause issues.

Are you sure your pointer is valid - perhaps you are using object after it was deleted?

Share this post


Link to post
Share on other sites

My code: https://pastebin.com/6GerYfna

And I'm using Visual Studio 2015, I guess with the default compiler.

5 minutes ago, Zaoshi Kaba said:

Most likely you have corrupted memory so vector<> became garbage and everything you do starts to cause issues.

Are you sure your pointer is valid - perhaps you are using object after it was deleted?

It also crashes when I just pushback a NULL and do nothing else

Share this post


Link to post
Share on other sites

Does crash occur if you call m_Pillars.empty()?

I don't see anything wrong with std::vector<Pillar*> m_Pillars, perhaps you could show how you use ObstacleManager class?

Share this post


Link to post
Share on other sites
3 minutes ago, Zaoshi Kaba said:

Does crash occur if you call m_Pillars.empty()?

I don't see anything wrong with std::vector<Pillar*> m_Pillars, perhaps you could show how you use ObstacleManager class?

Yes, it crashes with any function of the vector.

Here's the PlayState class, that uses the ObstacleManager. It calls the init, update, draw and clean functions.

https://pastebin.com/UhpkdP6i

Share this post


Link to post
Share on other sites
Just now, Robin04 said:

Here's the PlayState class, that uses the ObstacleManager. It calls the init, update, draw and clean functions.

I don't see where you call m_obstacleManager = new ObstacleManager();. How do you initialize it?

Share this post


Link to post
Share on other sites
7 minutes ago, Zaoshi Kaba said:

I don't see where you call m_obstacleManager = new ObstacleManager();. How do you initialize it?

Ooooo. Thats what i missed!! Thank you!! :))

And I also had another mistake: I forgot to give value to the m_Speed and m_pillarDensity member variables, so I had a division with 0.

Now it works. Thank you! :)

Share this post


Link to post
Share on other sites
47 minutes ago, Robin04 said:

I have also spotted an issue in another method:

std::vector<SDL_Rect*>* ObstacleManager::getCollisionRectVector()
{
    std::vector<SDL_Rect*> collisionRects;
    for (int i = 0; i < m_Pillars.size(); i++)
    {
        collisionRects.push_back(m_Pillars[i]->getCollisionRect());
    }
    return &collisionRects;
}

You create collisionRects on the stack, but then return pointer to it - after it gets destroyed. Eventually this will cause hard-to-diagnose crashes. Either return a copy or use new ..() and return pointer.

Edited by Zaoshi Kaba

Share this post


Link to post
Share on other sites
On 12/26/2017 at 2:07 PM, Zaoshi Kaba said:

I have also spotted an issue in another method:


std::vector<SDL_Rect*>* ObstacleManager::getCollisionRectVector()
{
    std::vector<SDL_Rect*> collisionRects;
    for (int i = 0; i < m_Pillars.size(); i++)
    {
        collisionRects.push_back(m_Pillars[i]->getCollisionRect());
    }
    return &collisionRects;
}

You create collisionRects on the stack, but then return pointer to it - after it gets destroyed. Eventually this will cause hard-to-diagnose crashes. Either return a copy or use new ..() and return pointer.

Thank you. I changed it. :)

Share this post


Link to post
Share on other sites

Also, some notes for improval on this very method:

std::vector<SDL_Rect*> ObstacleManager::getCollisionRectVector()
{
    std::vector<SDL_Rect*> collisionRects;
    collisionRects.reserve(m_Pillars.size()); // #1
  
    for(auto* pillar : m_Pillars) // #2
    {
        collisionRects.push_back(pillar->getCollisionRect());
    }
    return collisionRects;
}

#1: You should always call reserve on a vector if you know how many elements you are going to put in, since otherwise you'll have unnecessary allocations/copies. Its a great optimization with little overhead if applied globally.

#2: If possible, you should use this "range-based for loop" style over manual index-counting (C++11 required). Its less to type/easier to read and harder to mess up.

Share this post


Link to post
Share on other sites

BTW - Why is ObstacleManager a pointer in the PlayState? Make it a member variable and you don't have to worry about memory leaking.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement