BAADF00D Access Violation - c++

Sorry to ask for an answer to something so probably simple, but I can't figure this one out by myself, it seems.
So, I have a header file, like so:
#ifndef LEVELMAP_H
#define LEVELMAP_H
#include "Constants.h"
class LevelMap
{
public:
LevelMap(int map[MAP_HEIGHT][MAP_WIDTH]);
~LevelMap();
int GetTileAt(unsigned int h, unsigned int w);
private:
int** mMap;
};
#endif LEVELMAP_H
And a .ccp file like so:
#include "LevelMap.h"
// 0 = empty, 1 = blocked
LevelMap::LevelMap(int map[MAP_HEIGHT][MAP_WIDTH])
{
//Allocate memory for the level map.
mMap = new int*[MAP_HEIGHT];
for(unsigned int i = 0; i < MAP_HEIGHT; i++)
{
mMap[i] = new int[MAP_WIDTH];
}
//Populate the array.
for(unsigned int i = 0; i < MAP_HEIGHT; i++)
{
for(unsigned int j = 0; j < MAP_WIDTH; j++)
{
mMap[i][j] = map[i][j];
}
}
}
LevelMap::~LevelMap()
{
//Delete all elements of the array.
for(unsigned int i = 0; i < MAP_HEIGHT; i++)
{
delete [] mMap[i];
}
delete [] mMap;
}
int LevelMap::GetTileAt(unsigned int h, unsigned int w)
{
if(h < MAP_HEIGHT && w < MAP_WIDTH)
{
return mMap[h][w];
}
return 0;
}
Now, I get an access violation on the 'return mMap[h][w];' line, and I can't for the life of me figure out a solution.
For context, GetTileAt() is being used to detect if a certain tile on the screen should allow the player to collide with it or not.

You are not giving the exact error message that you get, but from the title I deduce that this is what you are looking at:
0xBAADF00D : Used by Microsoft's debug HeapAlloc() to mark uninitialized allocated heap memory
Which in your case would mean that mMap was never created. Try to delete all default constructors to find the exact error causing this. The default move, copy, and empty constructors will not work properly anyways, so it is good practice to delete them!

Related

Trying to copy a 2D dimensional array of objects to another function

I'm trying to copy an array from one class to to another class by passing it to a function but I'm running into issues. The array that I'm trying to copy seems to lose all its data.
// A.h
class A
public:
virtual void Test();
private:
A* array2D[30][32];
// A.cpp
void A::Test()
{
B* f = new B();
f->pass(array2D);
}
// B.h
class A;
class B
{
public:
void pass(A *a[][32]);
private:
A *a[30][32];
}
// B.cpp
void B::pass(A *array2D[][32])
{
for (int i = 0; i <= 30; i++)
{
for (int j = 0; j <= 32; j++)
{
a[i][j] = array2D[i][j];
}
}
}
My guess is that it's happening when I'm passing it but I'm not sure what I'm doing wrong.
My guess is that it's happening when I'm passing it but I'm not sure what I'm doing wrong.
First, your for loops to populate the array go out-of-bounds on the last iteration of the nested for loop:
void B::pass(A *array2D[][32])
{
for (int i = 0; i <= 30; i++) // This goes out-of-bounds on the last iteration
{
for (int j = 0; j <= 32; j++) // This also goes out-of-bounds.
{
a[i][j] = array2D[i][j];
}
}
}
Using <= in a for loop is an indication that things can go wrong, and they do go wrong with your code. The fix would simply be:
void B::pass(A *array2D[][32])
{
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 32; j++)
{
a[i][j] = array2D[i][j];
}
}
}
This will work, however it is inefficient (unless a great optimizing compiler sees that this is inefficient and changes the code).
The better way to do this is a simple call to std::copy:
#include <algorithm>
void B::pass(A *array2D[][32])
{
std::copy(&array2D[0][0], &array2D[29][32], &a[0][0]);
}
The reason why this works is that two-dimensional arrays in C++ have their data layout in contiguous memory, thus it is essentially a one-dimensional array. So giving the starting and ending address of the array elements is all that's required.
A compiler will more than likely see that you are copying a trivially-copyable type (a pointer), thus the call to std::copy results in a call to memcpy.

How can return a matrix pointer in c++?

I have a big problem, i want to put a matrix pointer of objects to a function but i don't know how can do this, the objects that i use they are from derived class. This is an example of my code. Note: class Piece is a base class and class Queen is a derived class from Piece
#include "Queen.h"
void changeToQueen(Piece* mx)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
mx[i][j] = new Queen();
}
}
}
int main()
{
Piece * matrix[7][7];
changeToQueen(matrix); // this fails
return 0;
}
You can change the input argument to void changeToQueen(Piece * mx[7][7]).
Or you can change the input argument to void changeToQueen(Piece** mx).
Change the assignment operator to mx[7*i + j] = new Queen(); and pass in the first element as input changeToQueen(&(matrix[0][0]));
The reason why both work is because multidimensional array elements are stored contiguously in memory. So all you need is a pointer to the first element.
Both solutions are a bit flawed because if you need to change the dimensions of your matrix, you have to change your code a bit. Changing your prototype to void changeToQueen(Piece** mx, size_t width, size_t height) will be helpful for the future.
Alternatively this could be a way to handle things
template <unsigned int rows, unsigned int columns>
class Board
{
public:
Board() {}
void changeToQueen()
{
for (unsigned int y = 0 ; y < rows ; ++y)
{
for (unsigned int x = 0 ; x < columns ; ++x)
{ _pieces[y][x] = Queen(); }
}
}
Piece &at(unsigned int row, unsigned int column)
{ return _pieces[row][column]; } // you should check for out of range
// you could either have a default null value for Piece to return, or throw an exception
private:
Piece _pieces[rows][columns];
};
int main()
{
Board<8,8> board;
board.changeToQueen();
// return 0; // this is not mandatory in c++
}
So, yeah, no pointers almost no worries ;)
You still want pointers?? uhm... okay maybe you could do that: Piece *_pieces[rows][columns];, i'm not sure you really need it, but I can't tell how much it would modify your existing code to do this.
First of all, I do not understand dependencies between Queen and Piece, so I suppose that Piece is super-type of Queen and assignment Piece * mx = new Queen(); is correct.
To fix the obvious problem of type mismatch you can change your
void changeToQueen(Piece* mx)
to
void changeToQueen(Piece* mx[7][7])
and with changing loops border to 7 (for (int i = 0; i < 7; i++)) or size of matrix to 8 x 8 (with the same loops) this will work.
But my suggestion is to think over method of storing data.
Perhaps you will need to build matrix of size different from 7x7, so consider the following example, where dynamic memory is used to store the matrix (in this example only Queen is used):
void changeToQueen(Queen*** &mx, int size)
{
mx = new Queen**[size]; // allocation of memory for pointers of the first level
for (int i = 0; i < size; i++)
{
mx[i] = new Queen*[size]; // allocation of memory for pointers of the second level
for (int j = 0; j < size; j++)
{
mx[i][j] = new Queen(); // allocation of memory for object
}
}
}
int main()
{
int m_size = 7;
Queen *** matrix = NULL; // now memory not allocated for matrix
changeToQueen(matrix, m_size);
return 0;
}
Note: & sign in void changeToQueen(Queen*** &mx, int size) allows to change pointer Queen *** matrix; inside the function changeToQueen

C++ 2D Array Initialization In Constructor - Program Runs Forever

I have a small class that creates a 2D array based on a variable size. The code I have for the class is as follows
class Treasure
{
int** board;
int size;
public:
Treasure(int boardSize)
{
board = new int* [boardSize];
for (int i = 0; i < size; i ++)
{
board[i] = new int[boardSize];
}
size = boardSize;
}
~Treasure()
{
for (int i = 0; i < size; i++)
{
delete [] board[i];
}
delete [] board;
board = NULL;
size = 0;
}
int get_value(int row, int col)
{
return board[row][col];
}
void set_value(int row, int col, int value)
{
board[row][col] = value;
}
};
I wanted to test my getter so I just ran some simple code:
int main(int argc, const char * argv[])
{
Treasure x1(2);
cout << x1.get_value(0, 0) << endl;
return 0;
}
For some reason when I ran the code the terminal window just had a flashing cursor and the CPU shot up to 100% and the memory usage went up to 1.5GB in a matter of seconds.
Does anyone have any idea on why this is happening? It's been awhile since I've used C++, so I might just be missing something obvious.
You are using size in your constructor before setting its value. So you will just have a garbage value there. Just move
size = boardSize;
up a few lines
In constructor, you didn't initialize "size" in the loop
for (int i = 0; i < size; i ++)
size here is undefined, and whatever garbage is here, it will be used in a loop
Just in support of the already provided answers, your size variable has been declared but not initialised! In such a case, you're leaving it up to the compiler to assign a value to size which may or may not be 0.
Rule of thumb is to always initialise variables to a value i.e. size = boardSize, even pointers in which case set them to NULL. Setting the "size" to the your input should fix the problem :)

Stack around variable is corrupted error

I am writing the following code and I am getting Stack around variable is corrupted error. I have checked similar posts but couldn't relate the problems. I am also rather new to C++. Here is my code.
///CLASS DEFINITION
class Trellis{
private:
int m;
int Nstates;
int StateTransition[];
public:
Trellis();
Trellis(int M);
};
Here is the definition of methods
Trellis::Trellis(int M){
m = M;
Nstates = pow(2, M - 1);
for (int i = 0; i < Nstates; i++){
StateTransition[i] = i;
}
}
int main()
{
Trellis Tu = Trellis(3);
return 0;
}
The error I get is Run-Time Check Failure #2-Stack around variuble 'Tu' was corrupted;
You're not allocating any memory for StateTransition, you want something like:
StateTransition = new int[Nstates];
before your for loop in the ctor.
Flexible array members were a C99 feature which allowed you to do something like
struct header {
size_t len;
unsigned char data[];
};
and, provided that you had a proper memory layout, you could access and write to the data array.
In your case you're not providing any memory for your StateTransition variable and thus overwriting some other stack data.
You had better doing something like
class Trellis
{
private:
int m;
int Nstates;
int *StateTransition; // Pointer
public:
Trellis();
Trellis(int M);
~Trellis();
};
Trellis::Trellis() : StateTransition(0) {
}
Trellis::Trellis(int M) : StateTransition(0)
{
m = M;
Nstates = pow(2, M - 1);
StateTransition = new int[Nstates]; // Allocate memory
for (int i = 0; i < Nstates; i++)
{
StateTransition[i] = i;
}
}
Trellis::~Trellis() {
if(StateTransition != 0)
delete[] StateTransition; // Always be a good citizen
}
And as for the rule of three, you might also want to write a copy constructor.

Assigning and Deleting Pointers

Okay, so here's the context. I've been up for almost a day straight now working on the legendary 8-puzzle problem. I have my heuristics down and my A_star algorithm down. We are required by the project spec to solve it using three different heuristic values. I can solve it for any one of the three individually, but when I go to solve them in succession, I get a ridiculous loop, and it never finds the correct successor state.
I believe my problem is with my pointers. I have a class, State, as defined below that has an int** array and a pointer to a State (its parent).
EDIT: I have to use int** as defined by the project specification, otherwise I would gladly use a pointer.
State (int **bd, State* prnt);
State (const State& other);
~State ();
I am then declaring them as such:
State::State(int **bd, State* prnt) {
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
board[i] = new int[3];
}
// fill in the board
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = bd[i][j];
//board[i][j] =
}
}
// set the parent
parent = prnt;
}
State::State(const State& other) {
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
board[i] = new int[3];
State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
delete board[i];
delete [] board;
delete parent;
parent = other.parent;
}
State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
delete board[i];
delete [] board;
delete parent;
}
State& State::operator=(const State &rhs) {
if (&rhs == this) {
return *this;
}
for (int i = 0; i < 3; i++) {
delete board[i];
}
delete [] board;
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
board[i] = new int[3];
}
// fill in the board
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//board[i][j] = rhs.board[i][j];
board[i][j] = rhs.getIntAtCoor(j, i);
}
}
//delete parent;
// set the parent
parent = rhs.parent;
// set g
g = rhs.g;
f = rhs.f;
hType = rhs.hType;
return *this;
}
I don't give the exact declarations -- some of it is simple like int = int. I just can't quite figure it out. I feel like either my delete parent is wrong or my parent = other.parent is wrong (or both).
Thank you for your time and help,
Tyler
Upgrading your code-style may force the errors to evaporate. In other words new and delete are error prone and should be avoided when better alternative exists.
For management of the cells consider:
std::shared_ptr: can be used to void the delete calls
std::vector can be used to avoid the new and delete calls
Note you should use it like std::vector<int> board( 3 * 3 ) and board.at( x + y * 3 ).
And best of all just use a static array int board[3][3]. No allocation at all.
Also child states do not own their parent states. It's the other way around. So child states shouldn't delete their parents. You can still safely keep a parent pointer, but make sure you cleanup the children before you allow a parent to go out of scope (deleted or otherwise). All of this cleaning and deleting doesn't neccessarily involve new at all. Your State class looks small enough that is doesn't matter if they are copied by value. In which case just have the parent use a std::vector<State> m_children and the compiler will take care of the rest.
You don't show the full definition of the copy constructor but I assume that the parent = other.parent line is in there. In that case, wouldn't the parent be responsible for its own lifetime and the delete parent in the destructor shouldn't exist at all.
Also note that you need to at least disable (private declaration) or implement the copy assignment operator.
Better still, use a vector of vector for your 2d array and let the language work for you.
Perhaps not a direct answer, but you are going against best practices for C++.
It's easier and definitely more maintainable to use vectors for this problem.
size_t row_sz = 3;
size_t col_sz = 3;
std::vector<int> board(row_sz * col_sz, 0);
int i = 0;
for (size_t r = 0; r < 0; r++)
for (size_t c = 0; c < 0; c++)
board[ r * row_sz + c ] = i++;
Multidimensional arrays are much easier handled with the above strategy as well. It just breaks less. If you really want the row/col access, write a wrapper around it.
struct Matrix {
int &operator()(size_t r, size_t c);
const int &operator()(size_t r, size_t c) const;
private:
std::vector<int> data;
};