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.
Related
I am trying to write a class where it starts with a small array to put values in. My objective is if the number of values exceed the capacity, the array expands to fit the remaining values. For example, if I had 5 numbers, the array would expand to accommodate the fifth value.
The object actually creates an array at run time. So when I wrote the function to expand, its actually creating a new array and pointing to it.
Heres the class
class DVec // self expanding array
{
private:
//[0...n-1] are the values, [0..cap-1] exist
int n;
double* a;
int cap;
void expand(double*);
public:
DVec(); // constructs an empty DVec
void add(double v); //adds v to the end of this DVec
int size();
double pop(); // removes and returns the last value (pre: not-empty)
double get(int idx); // returns value at idx in this DVec
void set(double v, int idx); // sets this DVec at idx to be v
};
Constructor
DVec::DVec()
{
cap = 4;
a = new double[cap];
n = 0;
}
Heres the code that I'm testing it with
void DVec::add(double v)
{
a[n++] = v;
if (n == cap) { expand(a); }
}
void DVec::expand(double*)
{
double* temp = new double[n*2];
for (int i = 0; i < n; i++)
{
temp[i] = a[i];
}
*a = *temp;
}
int main()
{
DVec a; DVec* p = new DVec();
for (int i = 0; i < 6; i++)
{
a.add(i * i);
}
cout << a.get(5);
}
My problem is that it keeps bombing out if I set the for loop to i<6. Anything lower its fine.
It comes back say it threw exception:
if (!has_cctor)
cexit();
My questions is what is this? Is it because I made a pointer equal a pointer(a* = *temp)? Or am I not even in the same galaxy as the correct way to write the function?
Edit:
Thanks for all the help guys. I made changes and it all works now.
{
double* temp = new double[cap++];
for (int i = 0; i < n; i++)
{
temp[i] = a[i];
}
a = temp;
}
DVec::DVec()
{
cap = 0;
a = new double[cap];
n = 0;
}
void DVec::add(double v)
{
if (n >= cap) { expand(a); }
a[n++] = v;
}
This line looks like the problem:
*a = *temp;
I assume you meant to replace a with temp, but what you've written is equivalent to this:
a[0] = temp[0]
You should write this instead:
a = temp;
You also need to remember to delete a before overwriting it, otherwise you will have a memory leak, as well as to update cap, or you will have further problems.
I assume you are doing this as an academic exercise rather than as a solution to a real-world problem. If not, you should use std::vector, as the standard library implementers have already done all the hard work for you.
I'm working on knight's tour problem, and want to define a class, but I am having trouble with initialize an array defined by user. So the user inputs from the command line argvs are the chessboard lengths mX and nY; and a starting position(x,y). So basically, how do I initialize an array that's defined by the user?
First question: In the public part, is it right to declare int ** tour?
Second question: How do I refer to the array tour in the following functions in the same class?
Third question: In main, I called K.knight to initialize an array of dimension specified by the user, but it wasn't initialized. How do I initialize an array in main using the function K.knigt(), and be able to use the array in the following function K.knightfunc()?
class Ktour{
public:
int xSize; //m
int ySize; //n
int ** tour; //array to be initialized
int solutionsCount; //tracking solutions
int position; //position count, from 0 to m * n -1
// initialize tour matrix
void knight(int M, int N) {
position = 1;
solutionsCount = 0;
xSize = M;
ySize = N;
tour = new int * [xSize];
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
tour[i][j] = 0;
std::cout << tour[i][j] << std::endl;
}
}
}
....some other functions defined in between...
....
....
};
...
// main
int main(int argc, char *argv[])
{
Ktour K;
//user inputs chessboard length mX and nY; and a starting position(x,y)
int mX = atoi(argv[1]);
int nY = atoi(argv[2]);
int x = atoi(argv[3]);
int y = atoi(argv[4]);
//initialization
K.knight(mX, nY);
//run the recursive function;
K.knightFunc(x,y);
return 0;
}
Yeah, it seems more logical to initialize in the ctor. My take on this is you are creating an array of int pointers, and have not yet allocated the ints that are being pointed to.
You have a few possibilities:
If we are to think of a common chessboard, then since the array size is known in advance, and it's not especially big, just create it in the class:
class Ktour{
...
int tour[8][8];
...
}
although some purists might say you should only "new" such arrays. If it is a much larger array, you certainly should.
A more straightforward syntax like what you're trying to do, for handling arrays of unknown size would be:
class Ktour{
...
int **tour=0;
KTour(int M, int N) {
tour = new int * [M];
for (int i=0; i<M; ++i)
tour[i] = new int [N];
};
~KTour() {
for (int i=0; i<M; ++i)
delete [] tour[i];
delete [] tour;
};
...
}
You access it quite simply, with:
std::cout << tour[i][j];
The above kind of coding is error-prone. To reduce your future strife with memory access errors, you really should use STL container classes (or Boost ones, or Qt ones when using Qt, if their size isn't too limited - but you can use STL in Qt also), since they produce an error in debug when you access out-of-bounds subscripts for your arrays, instead of, e.g. overwriting important pointers, etc. Thus, you could use something like:
class Ktour{
...
std::vector < std::vector<int> > Tour;
KTour(int M, int N) {
// tour.resize(M); // not needed.
tour.assign(M, std::vector <int> (N, 0));
};
~KTour() {
// No need to delete
};
...
}
and you access it with
std::cout << tour[i][j];
(Note: The extra lines in the code are some artifact of the <pre> and <code> tags; necessitated by not all of my indented lines being recognized as code.)
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
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!
Ok, so I'm quite new to C++ and I'm sure this question is already answered somewhere, and also is quite simple, but I can't seem to find the answer....
I have a custom array class, which I am using just as an exercise to try and get the hang of how things work which is defined as follows:
Header:
class Array {
private:
// Private variables
unsigned int mCapacity;
unsigned int mLength;
void **mData;
public:
// Public constructor/destructor
Array(unsigned int initialCapacity = 10);
// Public methods
void addObject(void *obj);
void removeObject(void *obj);
void *objectAtIndex(unsigned int index);
void *operator[](unsigned int index);
int indexOfObject(void *obj);
unsigned int getSize();
};
}
Implementation:
GG::Array::Array(unsigned int initialCapacity) : mCapacity(initialCapacity) {
// Allocate a buffer that is the required size
mData = new void*[initialCapacity];
// Set the length to 0
mLength = 0;
}
void GG::Array::addObject(void *obj) {
// Check if there is space for the new object on the end of the array
if (mLength == mCapacity) {
// There is not enough space so create a large array
unsigned int newCapacity = mCapacity + 10;
void **newArray = new void*[newCapacity];
mCapacity = newCapacity;
// Copy over the data from the old array
for (unsigned int i = 0; i < mLength; i++) {
newArray[i] = mData[i];
}
// Delete the old array
delete[] mData;
// Set the new array as mData
mData = newArray;
}
// Now insert the object at the end of the array
mData[mLength] = obj;
mLength++;
}
void GG::Array::removeObject(void *obj) {
// Attempt to find the object in the array
int index = this->indexOfObject(obj);
if (index >= 0) {
// Remove the object
mData[index] = nullptr;
// Move any object after it down in the array
for (unsigned int i = index + 1; i < mLength; i++) {
mData[i - 1] = mData[i];
}
// Decrement the length of the array
mLength--;
}
}
void *GG::Array::objectAtIndex(unsigned int index) {
if (index < mLength) return mData[index];
return nullptr;
}
void *GG::Array::operator[](unsigned int index) {
return this->objectAtIndex(index);
}
int GG::Array::indexOfObject(void *obj) {
// Iterate through the array and try to find the object
for (int i = 0; i < mLength; i++) {
if (mData[i] == obj) return i;
}
return -1;
}
unsigned int GG::Array::getSize() {
return mLength;
}
I'm trying to create an array of pointers to integers, a simplified version of this is as follows:
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
Now the problem is that the same pointer is used for j in every iteration. So after the loop:
array[0] == array[1] == array[2];
I'm sure that this is expected behaviour, but it isn't quite what I want to happen, I want an array of different pointers to different ints. If anyone could point me in the right direction here it would be greatly appreciated! :) (I'm clearly misunderstanding how to use pointers!)
P.s. Thanks everyone for your responses. I have accepted the one that solved the problem that I was having!
I'm guessing you mean:
array[i] = &j;
In which case you're storing a pointer to a temporary. On each loop repitition j is allocated in the stack address on the stack, so &j yeilds the same value. Even if you were getting back different addresses your code would cause problems down the line as you're storing a pointer to a temporary.
Also, why use a void* array. If you actually just want 3 unique integers then just do:
std::vector<int> array(3);
It's much more C++'esque and removes all manner of bugs.
First of all this does not allocate an array of pointers to int
void *array = new void*[2];
It allocates an array of pointers to void.
You may not dereference a pointer to void as type void is incomplete type, It has an empty set of values. So this code is invalid
array[i] = *j;
And moreover instead of *j shall be &j Though in this case pointers have invalid values because would point memory that was destroyed because j is a local variable.
The loop is also wrong. Instead of
for (int i = 0; i < 3; i++) {
there should be
for (int i = 0; i < 2; i++) {
What you want is the following
int **array = new int *[2];
for ( int i = 0; i < 2; i++ )
{
int j = i + 1;
array[i] = new int( j );
}
And you can output objects it points to
for ( int i = 0; i < 2; i++ )
{
std::cout << *array[i] << std::endl;
}
To delete the pointers you can use the following code snippet
for ( int i = 0; i < 2; i++ )
{
delete array[i];
}
delete []array;
EDIT: As you changed your original post then I also will append in turn my post.
Instead of
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
there should be
Array array;
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject( new int( j ) );
}
Take into account that either you should define copy/move constructors and assignment operators or define them as deleted.
There are lots of problems with this code.
The declaration void* array = new void*[2] creates an array of 2 pointers-to-pointer-to-void, indexed 0 and 1. You then try to write into elements 0, 1 and 2. This is undefined behaviour
You almost certainly don't want a void pointer to an array of pointer-to-pointer-to-void. If you really want an array of pointer-to-integer, then you want int** array = new int*[2];. Or probably just int *array[2]; unless you really need the array on the heap.
j is the probably in the same place each time through the loop - it will likely be allocated in the same place on the stack - so &j is the same address each time. In any case, j will go out of scope when the loop's finished, and the address(es) will be invalid.
What are you actually trying to do? There may well be a better way.
if you simply do
int *array[10];
your array variable can decay to a pointer to the first element of the list, you can reference the i-th integer pointer just by doing:
int *myPtr = *(array + i);
which is in fact just another way to write the more common form:
int *myPtr = array[i];
void* is not the same as int*. void* represent a void pointer which is a pointer to a specific memory area without any additional interpretation or assuption about the data you are referencing to
There are some problems:
1) void *array = new void*[2]; is wrong because you want an array of pointers: void *array[2];
2)for (int i = 0; i < 3; i++) { : is wrong because your array is from 0 to 1;
3)int j = i + 1; array[i] = *j; j is an automatic variable, and the content is destroyed at each iteration. This is why you got always the same address. And also, to take the address of a variable you need to use &