i have to implement a small and simple game in c++ (a maze) and I have some problems right now.
Some snippets:
I've got an array of object pointers which represents my fields in the maze
Field*** maze;
init of the maze:
for (n = 0; n < MAZE_WIDTH; n++) {
this->maze[n] = new Field*[MAZE_HEIGHT];
for (p = 0; p < MAZE_HEIGHT; p++) {
this->maze[n][p] = new Field();
this->maze[n][p]->x = n;
this->maze[n][p]->y = p;
}
}
When creating the maze i need a list of already visited fields and a stack
so I did:
std::vector<Field*> visited;
std::vector<Field*> stack;
Then later I want to put a Field* into my stack
stack.push_back(neighbour);
But after this push all values in the object are wrong.
Even if i try
neighbour = stack.back();
all the values are completly different
I already red some threads about this topic and that's why i chose a vector of pointers and not objects.
Where is my fault?
Edit:
Some more snippets as requested:
Of course I allocate memory for the mate itself
this->maze = new Field**[MAZE_WIDTH];
Field is a simple class which looks like:
class Field {
public:
Field();
~Field();
bool w_left;
bool w_right;
bool w_front;
bool w_back;
unsigned int x;
unsigned int y;
private:
};
Since, you didn't posted the code of how you are obtaining the values,
compare to this, and try to find your problem...
std::vector<std::vector<Field*> > maze;
// Ini
for(int i = 0; i < MAZE_WIDTH; i++)
{
maze.push_back(std::vector<Field*>());
for(int j = 0; j < MAZE_HEIGHT; j++)
{
maze[i].push_back(new Field());
maze[i][j]->x = i;
maze[i][j]->y = j;
}
}
std::vector<Field*> visited;
// push the field [4,5] in a visited vector
visited.push_back(maze[4][5]);
// Clean up
for(size_t i = 0; i < maze.size(); i++)
{
for(size_t j = 0; j < maze[i].size(); j++)
delete maze[i][j];
}
Why declare the maze as Field***?
The C++ alternative is std::vector<std::vector<Field*> > maze;, and that's what you should use.
Related
I have a class called ContactInfo and is structured as written below:
class ContactInfo
{
private:
string contactName;
string contactNumber;
public:
ContactInfo()
{
contactName = "";
contactNumber = "";
}
//setter and getters
};
and I have a function that creates an array of ContactInfo and populates it via user input. After populating the array it would be passed to another function that would sort it, the said function is written as shown below.
void sortListByName(ContactInfo contactList[], int listSize)
{
for(int i = 0; i < listSize; i++)
{
for(int j = i+1; j < listSize+1; j++)
{
if(contactList[i].getContactName() > contactList[j].getContactName())
{
ContactInfo temp = contactList[j];
contactList[i] = contactList[j];
contactList[j] = temp;
}
}
}
}
The main method
int main()
{
...
int n;//array size
ContactInfo *newList = contactList(n);//populates the array.
sortListByName(newList, n);
...
}
The problem is that the program would terminate before the sorting would happen and produce the error:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Look at the upper bound of your inner loop. Notice that we can have j equal to the size of the array for the last iteration.
In C++, an array of size N has its elements indexed from 0 to N-1. In your case, you're trying to access an element past the end of the array, and are running into Undefined Behaviour. Ensure your index is within the bounds of the array.
Secondly, you should be using std::vector over raw arrays wherever possible anyways.
Third, the standard library provides the std::sort algorithm for you, which will almost always be faster than the bubble sort that you have implemented.
Your error is made in sort algorithm in the last iteration.
The thing is, that in first for loop variable i goes from 0 to listSize,
and in second for loop variable j goes from i+1 to listSize+1. When variable i reaches listSize-1, variable j will start from i+1 in the second for loop. This means j=listSize, and then when you try to access contactList[j] an error is going to occur because elements of contactList start from index 0 and end with index listSize-1.
void sortListByName(ContactInfo contactList[], int listSize)
{
for(int i = 0; i < listSize; i++) //it should be for(int i=0;i<listSize-1;i++)
{
//here is your mistake. When i = listSize-1 then j=listSize and
// that index is out of range.
for(int j = i+1; j < listSize+1; j++) //it should be for(int j=i+1;j<listSize;j++)
{
if(contactList[i].getContactName() > contactList[j].getContactName())
{
ContactInfo temp = contactList[j];
contactList[i] = contactList[j];
contactList[j] = temp;
}
}
}
}
this is how your code should look like:
void sortListByName(ContactInfo contactList[], int listSize)
{
for(int i = 0; i < listSize-1; i++)
{
for(int j = i+1; j < listSize; j++)
{
if(contactList[i].getContactName()> contactList[j].getContactName())
{
ContactInfo temp = contactList[j];
contactList[i] = contactList[j];
contactList[j] = temp;
}
}
}
I am studying the vector array with my assignment, and with this assignment I have some question that is about the two dimension vector array.
THE ASSIGNMENT is : List the current process with show up their parent-child relation.
Question
I want to pass the vector value just ppids[i] to do this I write it only write
vector<process*>
If my function parameter declare like
vector<vector<process*>>
it must write "ppids" so it is not my intent.
Error
Cannot convert 1 parameter from 'std::vector<process *,std::allocator<_Ty>>'to 'std::vector &'
So, here is my codes. (Just a part of my code)
Struct Vector :
struct process {
string procName;
DWORD procPid;
DWORD procPpid;
};
main vector, get process information on msdn API
std::vector <process*> myProcess;
part of main below...
//
// Group Vector by PPid
//****(here is 2 dimension vector)****
std::vector< std::vector< process* > > ppids;
int n = 0;
int index = 1;
for (int i = 0, size = tempPid.size(); i < size; ++i) {
ppids.push_back(vector<process*>());
for (int j = 0, size2 = myProcess.size(); j < size2; ++j) {
if (myProcess[j]->procPpid == tempPid[i]) {
ppids[n].push_back(myProcess[j]);
};
}
for (int k = 0, size3 = ppids[n].size(); k < size3; ++k)
{
_tprintf(TEXT("%d \t"), index);
index++;
_tprintf(TEXT("[%s]"), ppids[n][k]->procName.c_str());
_tprintf(TEXT("[%d]"), ppids[n][k]->procPid);
_tprintf(TEXT("[%d] \n"), ppids[n][k]->procPpid);
}
n++;
}
myProcess.clear();
the function is called on here.
// Combine vector
myProcess = ppids[0];
std::vector <process*> tmpProcess;
for (int i = 1, size = ppids.size(); i < size; ++i) {
tmpProcess = combine(myProcess, ppids[i]);
myProcess.clear();
myProcess = tmpProcess;
}
and finally, this is my function.
vector<process*> combine(vector<process*> tempA, vector<process*> tempB) {
std::vector <process*> alloProcess;
for (int i = 0, size = tempA.size(); i < size; ++i) {
if (tempA[i]->procPid == tempB[1]->procPpid)
{
alloProcess.push_back(tempA[i]);
for (int j = 0, size2 = tempB.size(); j < size2; ++j) {
alloProcess.push_back(tempB[j]);
}
}
else {
alloProcess.push_back(tempB[i]);
}
}
return alloProcess;
}
Full codes on here:
https://gist.github.com/anonymous/25e636086bbfacbec78508736935d3af
void function(vector< vector<process> > *matrix)
Specifies a pointer, it is essentially passed by reference. However, in C++, it's better to avoid pointers and pass a reference directly:
void function(vector< vector<process> > &matrix)
and
function(matrix1); // Function call
I'm trying to create two dimensional array and assign objects into it. What's important is, that I want to do this using POINTERS. I want to achieve it like this:
Create pointer which will point to array of pointers.
Having array pointers I create next 10 cells in memory for example to store there individual object.
This is my code:
I create basic pointer for storing the address for array of pointers:
SpecialPoint **arrayOfPointsOnTheMap = NULL;
Next I initialize this array:
arrayOfPointsOnTheMap = new SpecialPoint*[size];
And then create cells in memory:
for (int i = 0; i < szer; i++) {
arrayOfPointsOnTheMap[i] = new SpecialPoint[wys];
}
And for the end I want to assign object to this newly created array:
SpecialPoint *pontInTable;
for (int i = 0; i < szer; i++) {
pontInTable = arrayOfPointsOnTheMap[i];
for (int j = 0; j < wys; j++) {
pontInTable[j] = new SpecialPoint();
}
}
But I get error when trying to create new object int array. I'm a little confused about it. Can anyone help?
What you want to do in the assignment part is not very clear so I will answer based on my best guess. Let`s say your class is as follows:
class SpecialPoint
{
public:
int x;
int y;
SpecialPoint(int xx, int yy)
{
x=xx;
y=yy;
}
SpecialPoint()
{
x=0;
y=0;
}
};
Then you can use the following code to create and initialize your 2d array:
int size = 4;
int wys = 3;
SpecialPoint** arrayOfPointsOnTheMap = new SpecialPoint*[size];
for(int i = 0; i < size; i++)
{
arrayOfPointsOnTheMap[i] = new SpecialPoint[wys];
} // you have your array at that point
SpecialPoint fakePoint(5,6); // create a special point
for(int i=0; i < size; i++)
{
for(int j=0; j < wys; j++)
{ // Assign your special point instance to all the array cells.
arrayOfPointsOnTheMap[i][j] = fakePoint;
}
}
After you are done with the array, do not forget to clean memory using:
for(int i = 0; i < size; i++) {
delete [] arrayOfPointsOnTheMap[i];
}
delete [] arrayOfPointsOnTheMap;
Good luck!
I am trying to create an array of Object pointers in order to sort some data. Here is my code:
ArrayClass<Exoplanet*> exoplanets;
int count = 0;
for (int i = 0; i < exosystems.size(); ++i) {
ArrayClass<Exoplanet> *temp = exosystems.at(i)->getPlanets();
for (int k = 0; k < temp->size(); ++k) {
exoplanets.add(&temp->at(k));
}
temp->~ArrayClass();
}
//check to see if pointer array is working properly
for (int i = 0; i < exoplanets.size(); ++i) {
exoplanets.at(i)->printPlanet();
cout << endl;
}
ArrayClass<Exoplanet> *Exosystem::getPlanets(void) const
{
return planets;
}
Also the getPlanets() function is included at the end for reference. Whenever I print the planets in the last for loop, all of the exoplanet pointers point to the last exoplanet returned from the getPlanet() function the final time through the 1st for loop. I think this has something to do with exoplanets.add(&temp->at(k)), but I am not sure how to fix it. Thanks in advance
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;
};