Exception thrown at 0xFDFDFDFD in Battleship.exe: 0xC0000005: Access violation executing location 0xFDFDFDFD

-1

i get an exception 0xFDFDFDFD, 0xfdfdfdfd is a magic value in the MSVC debug heap implementation that's put as a canary directly before and behind an allocated region of storage. Somehow you're using it as a pointer and writing to it.

It's difficult to say with certainty what the error is, since you didn't think it necessary to show any code. I suspect one of two things:

You allocate a pointer array and use the "element" behind the last element uninitialized, or (more likely) You allocate an array of objects (or possibly a vector) whose first data member is a pointer and do the same. The reason I think the latter more likely is that using pointers in the pointer array uninitialised would break before you got to the end, so you'd have to start at the end, which would be an unusual thing to do. When i comment my_board.set_ship(location, direction, ship);, it works normally. I found some similiar questions, but they didn't help me, here is some of them

Access violation reading location 0xFDFDFDFD

Access violation writing location 0xfdfdfdfd

Main

#include "internship.h"
#include "juniorship.h"
#include "middleship.h"
#include "seniorship.h"
#include "board.h"
#include <iostream>

int main() {
    Location location(1, 2);
    Direction direction = get_random_direction();
    Ship* ship = new InternShip();

    Board my_board;
    my_board.set_ship(location, direction, ship);
    std::string s = my_board.get_board()[0][0]->get_image();  // Exception thrown here

    return 0;
}

class Board

#ifndef BOARD_H
#define BOARD_H

#include <vector>
#include "ship.h"
#include "location.h"
#include "utils.h"
#include "object.h"
#include "water.h"
#include <stdexcept>


class Board {
public:
    using Matrix = std::vector<std::vector<Object*>>;
private:
    Matrix m_board;
public:
    Board() {
        m_board =  Matrix(10, std::vector<Object*>(10));

        for (size_t i = 0; i < 10; ++i) {
            for (size_t j = 0; j < 10; ++j) {
                m_board[i][j] = &Water();
            }
        }
    };

    ~Board() { };

    Matrix get_board() const { return m_board; };

    void set_ship(Location location, Direction direction, Ship* ship) {
        for (size_t i = 0; i < ship->get_health(); ++i) {
            if (direction == HORIZONTAL) {
                m_board[location.get_x() + i][location.get_y()] = ship;
            }
            else if (direction == VERTICAL) {
                m_board[location.get_x()][location.get_y() + i] = ship;
            }
            else {
                throw std::logic_error("Invalid Direction");
            }
        }
    };
};

#endif // BOARD_H

class Object

#ifndef OBJECT_H
#define OBJECT_H

#include <string>

class Object {

public:
    Object() {};
    ~Object() {};
    virtual std::string get_image() { return "o"; };
};

#endif // OBJECT_H

class Water

#ifndef WATER_H
#define WATER_H

#include "object.h"
#include <string>

class Water : public Object {
private:
    std::string m_image = "~";
public:
    Water() {};
    ~Water() {};
    std::string get_image() override { return m_image; };
};

#endif // WATER_H

class Ship

#ifndef SHIP_H
#define SHIP_H

#include "utils.h"
#include "location.h"
#include "player.h"
#include <string>
#include "object.h"

class Ship : public Object{
private:
    // Number from [0..4] where 0 is dead.
    size_t m_health = 0;
    std::string m_image = " ";

public:
    Ship() { };
    Ship(size_t health, std::string image) : m_health(health), m_image(image) { };
    virtual ~Ship() { };

    std::string get_image() override { return m_image; };
    size_t get_health() { return m_health; };

};

#endif // SHIP_H

class InternShip

#ifndef INTERNSHIP_H
#define INTERNSHIP_H

#include "ship.h"

class InternShip : public Ship {

public:
    InternShip() : Ship(1, "*") { };
    ~InternShip() override { };
    std::string get_image() override { return this->get_image(); };

};

#endif // INTERNSHIP_H

Utils

#ifndef UTILS_H
#define UTILS_H

#include <cstdlib>

enum Countries {
    ENGLAND,
    FRANCE,
    ARMENIA,
    RUSSIA
};

enum Color {
    RED,
    GREEN,
    BLUE,
    PURPLE
};

enum Direction {
    HORIZONTAL,
    VERTICAL
};

// Returns a random direction.
Direction get_random_direction() {
    int random = std::rand() % 2;
    // could return Direction(random);
    switch (random) {
    case 0:
        return Direction::HORIZONTAL;
    case 1:
        return Direction::VERTICAL;
    default:
        throw "Random number not in range [0..1].";
    }
};

#endif // UTILS_H
c++
oop
asked on Stack Overflow Feb 8, 2020 by Levon

1 Answer

0

@Fran├žois Andrieux is right, &Water(); creates a temporary Water object, takes it's address then immediately destroys the temporary Water. As soon as i get that pointer it's already invalidated and can't be used.

Here is the right section of code.

class Board {
public:
    using Matrix = std::vector<std::vector<Object*>>;
private:
    Matrix m_board;
    Object* m_obj;
public:
    Board() {
        m_board =  Matrix(10, std::vector<Object*>(10));
        m_obj = new Water();

        for (size_t i = 0; i < 10; ++i) {
            for (size_t j = 0; j < 10; ++j) {
                m_board[i][j] = m_obj;
            }
        }
    };

    ~Board() { delete m_obj; };
};
answered on Stack Overflow Feb 8, 2020 by Levon • edited Feb 8, 2020 by Levon

User contributions licensed under CC BY-SA 3.0