SFML community forums

Help => Graphics => Topic started by: Ago19 on October 22, 2019, 11:10:30 pm

Title: Access violation reading location
Post by: Ago19 on October 22, 2019, 11:10:30 pm
I'm trying to recreate space invaders but it gives me this error

main:
#include <SFML/Graphics.hpp>
#include <iostream>
#include "Collision.hpp"
#include "Enemy.h"
#include "Ship.h"
#include "Entity.h"
#include "Bullet.h"
#include <vector>

int width = 608, height = 1080;

std::vector<Enemy*> e;

int main()
{
        sf::RenderWindow window(sf::VideoMode(width, height), "SFML works!",sf::Style::Close);
       
        for (int i = 0; i < 5; i++) {
                Enemy * enemy = new Enemy(i);
                e.push_back(enemy);
        }

        for (int i = 0; i < e.size(); i++) {
               
        }

        Ship ship;
        Bullet bullet;

        while (window.isOpen())
        {
                sf::Event evnt;
                while (window.pollEvent(evnt))
                {
                        switch (evnt.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        case sf::Event::KeyPressed:
                                switch (evnt.key.code)
                                {
                                case sf::Keyboard::A:
                                        ship.sprite.move(-ship.speed, 0);
                                        break;
                                case sf::Keyboard::D:
                                        ship.sprite.move(ship.speed, 0);
                                        break;
                                case sf::Keyboard::Space:
                                        if (bullet.Exist == false) {
                                                bullet.Shoot(ship);
                                        }
                                        break;
                                default:
                                        break;
                                }
                                break;
                        default:
                                break;
                        }
                }

                for (int i = 0; i < e.size(); i++) {
                        if (Collision::PixelPerfectTest(bullet.sprite, e[i]->sprite)) {
                                e[i]->alive = false;
                        }

                        if (e[i]->alive == false) {
                                e.erase(e.begin() + i);
                                delete e[i];
                        }
                }
               

               

               

                if (bullet.sprite.getPosition().y + bullet.texture.getSize().y * bullet.scale < 0) {
                        bullet.Exist = false;
                }
                ship.keepInMap();

                window.clear(sf::Color::Black);
                for (int i = 0; i < e.size(); i++) {
                        window.draw(e[i]->sprite);
                }
                if (bullet.Exist == true) {
                        bullet.sprite.move(0, -bullet.speed);
                        window.draw(bullet.sprite);
                }
                window.draw(ship.sprite);
                window.display();
        }

        return 0;
}
 

Enemy Class
#pragma once
#include "Entity.h"

extern int width, height;

class Enemy : public Entity {
public:

        float scale;
        bool alive;

        Enemy(int position) {
                alive = true;
                texture.loadFromFile("../Textures/enemy.png");
                sprite.setTexture(texture);
                sprite.setPosition(width / 5 * position, 0);
                scale = 0.1;
                sprite.setScale(scale, scale);
        }

        bool isDead() {
                if (alive == true) {
                        return false;
                }
                else return true;
        }


};

 

Entity Class:
#pragma once
#include <SFML/Graphics.hpp>

class Entity {
public:
        int speed = 15;
        enum Direction { LEFT = 0, RIGHT = 1 };
        sf::Texture texture;
        sf::Sprite sprite;
        Direction dir;

        Entity() {
               
        }
};
 

It generatoes the error when the bullet hits and delete the enemy object in the vector e
Title: Re: Access violation reading location
Post by: eXpl0it3r on October 23, 2019, 01:12:32 pm
You're deleting the vector within the loop where you're iterating over the vector. After the loop ends, it will execute the check e.getSize() but since you deleted the vector, your application crashes.

I highly recommend you learn a bit on how to use a debugger, as the debugger would've pointed you at the place where things go wrong and you can inspect the variable state and eventually figure out what goes wrong.

Also you really shouldn't be using new and delete anymore, as C++11 and C++14 have introduced smart pointer constructs that guarantee proper memory handling.
In your case, you don't even need to create enemies with new instead you can just emplace_back(i) the enemy in the vector itself.