Trouble finding memory leak (deleting double pointer) - c++

So I'm writing a program which uses a double pointer in some somewhat deep recursion, and I've got a huge memory leak which I can't find the source of. The way the program works is (and I'll post some sample code below) that there is a board object with a double pointer called "board" which is the real board (it's a connect 4 game) and another double pointer called "newBoard" which is what is used by a function called minimax() (outside of the Board class).
minimax() is recursive, stepping through each possible route the game could take, and since I don't want to edit the actual board at all, and I figured copying the entire "board" object thousands and thousands of times would be unncecessary, I thought that creating this "newBoard" pointer to copy the actual board would be the best option.
I have a function to delete newBoard, but it's not working like I'd like it to. Here are the relevant pieces of code:
minimax():
void Brain::minimax(Board board, int who, int currentCheck, int iter)
{
board.createNewBoard();
if (iter <= MAX_ITER)
{
for (int i = 0; i < w_; i++)
{
if (board.playMove(i, currentCheck))
{
if (winDetect(board, board.getDisc('c')))
{
if (iter == 0)
{
score[i] += 1000;
}
else
score[i] += (MAX_ITER - iter);
}
else if (winDetect(board, board.getDisc('p')))
{
if (iter == 1)
{
score[i] += 500;
}
else
score[i] -= (MAX_ITER - iter);
}
else if (!winDetect(board, board.getDisc('c')) && !winDetect(board, board.getDisc('p')))
{
if (currentCheck == board.getDisc('p'))
currentCheck = board.getDisc('c');
else if (currentCheck == board.getDisc('c'))
currentCheck = board.getDisc('p');
minimax(board, who, currentCheck, iter + 1);
}
}
}
}
}
createNewBoard():
void Board::createNewBoard()
{
newBoard = new int*[h_];
for (int i = 0; i < h_; i++)
newBoard[i] = new int[w_];
}
NB_delete():
void Board::NB_delete()
{
for (int i = 0; i < w_; i++)
delete[] newBoard[i];
delete[] newBoard;
}
I think that's all the relevant code, but if you think there might be more, let me know and I'll include it! Thanks in advance for any help.
EDIT: SOLVED
I had simply forgotten to call my NB_delete() function. Calling it fixed the program!

As far as I can see, newBoard is a member of class Board. Now minimax is called recursively and so is CreateNewBoard. That means: In CreateNewBoard you are overwriting newBoard in each successive recursive call! That's probably your memory leak.
If CreateNewBoard is to be called recursively, you need a separate instance of newBoard for each level of recursion. Or is newBoard a 2D array for that very reason and the h_ index denotes recursion depth? In that case you should not create a new instance of newBoard in iteration 2 ... h_.

Related

C++ There is a bool return type function returning (24) here

First of all sorry for too much code
Here there is a vector (teamNum) with type class, the class contain a vector (player) with type struct, it is a little complicated, but here in this function I need to check if there is a player in teamNum which contain tName equal to _tname (function parameter) contain (the player) pID equal to _pID (function parameter)
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
if (teamNum[i].tName == _tname)
{
for (int j = 0; j < teamNum[i].player.size(); j++)
{
if (teamNum[i].player[j].pID == _pID)
return true;
}
}
else if (i == (teamNum.size() - 1))
{
return false;
}
}
}
And in the main
int main()
{
cout << "\n" << thereIsSimilarID("Leverpool", 1) << endl;
}
The output is 24 !!!!!
(good note that this happen just when the team (Leverpool) is the last team in the vector teamNum)
Again sorry for too much code but I need to know the bug not only fix the problem I need to learn from you
You encountered undefined behaviour.
If you take the if (teamNum[i].tName == _tname)-branch on the last element, but find no player with the correct pID, you don't return anything. Which means, that the return value is whatever random value is currently in the memory location that should hold the return value. In your case it happens to 24. But theoretically, everything could happen.
The same problem occurs when teamNum is empty.
The solution is to make sure to always return a value from a function (except if it has return type void of course):
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
// In this loop return true if you find a matching element
}
// If no matching element was found we reach this point and make sure to return a value
return false;
}
You should take a look at your compiler settings and enable all the warnings. And often it's good to let it treat certain warnings as errors.

How to access public variables from within their own class's member functions? (C++)

I would like to access a public variable I declared at the beginning of my class from one of its member functions. But it's saying it's out of scope.
Goban::Goban (constructor) works great. It successfully accesses and changes the values of both "board" and "isWhiteToPlay", as intended.
printBoard's code worked when it was in the program which is calling this class, but now that I've moved it here, attempts to compile are met with "‘board’ was not declared in this scope". Neither board nor isWhiteToPlay escape the same fate in playMove.
What am I doing wrong here? It's a public variable, but it shouldn't even need to be since I'm still in the class, right? Is there an easy way to access and modify Goban's variables from within Goban's functions? I would not look forward to having to treat board as a pointer in order to pass it to the function and then return it. I think I could do it, but I can't imagine there's not a vastly more elegant way.
class Goban
{
public:
int board[9][9]; // y,x -1 = W +1 = B
int captures[2];
bool isWhiteToPlay; // 0 for Black's turn, 1 for White's turn
Goban();
void printBoard(); // Prints the board to the terminal wherefrom the program is called.
void playMove(int x, int y); // Makes a move for the turn player at the coordinate (x,y). Right now I'm just trying to get it to change the value of the proper coordinate of "board" and not caring if the move is legal.
};
Goban::Goban() // Just initializing everything to zero here for now. Interesting to note that there are no compiling errors in this constructor. But later it complains when I use board and isWhiteToPlay elsewhere. The only difference I can see is that here they're in for loops, and there they're in if clauses. Not sure why that would make a difference, nor how to work around it.
{
captures[0] = 0;
captures[1] = 0;
for (int j = 0; j <= 8; j++)
{
for (int i = 0; i <=8; i++)
{
board[j][i] = 0;
}
}
isWhiteToPlay = 0;
}
void printBoard() // This code worked correctly when it was in the program, but the problem started when I moved it here to the class.
{
for (int j = 0; j <= 8; j++)
{
for (int i = 0; i <= 8; i++)
{
if (board[j][i] == -1)
{ std::cout << " O"; }
else if (board[j][i] == 1)
{ std::cout << " X"; }
else
{ std::cout << " ."; }
}
}
}
void playMove(int x, int y) // Same errors as above; solution is probably the same.
{
if (isWhiteToPlay == 0)
{
board[y][x] = -1;
isWhiteToPlay = 1;
}
else
{
board[y][x] = 1;
isWhiteToPlay = 0;
}
}
I suspect someone has probably already asked this question, but I think I'm just not coming up with the right search terms, which is probably an indication that I don't fully understand what I'm doing wrong here. If anyone understands the problem I have well enough to know the right search terms, a link to the appropriate extant stackoverflow thread would be welcome. Of course, I wouldn't complain about answers here, but no need to reinvent the wheel, and all that.
You mean to have Goban::printBoard and Goban::playMove. As it is, you are simply declaring + defining free functions.
e.g.
void Goban::printBoard()
{
}
Just like you have for your constructor:
Goban::Goban()
{
}
I assume when you say
printBoard's code worked when it was in the program which is calling this class
You mean that it used to work when you had the code in the class declaration, but you've now moved them into a separate definition.

NullReferenceException on push_back

I am getting a nullReferenceException when using vector.push_back on a new object.
In the code segment you see I have the vector object as a pointer but I originally had it as a non-pointer, I changed it in my troubleshooting out of desperation.
I stepped through the instantiation of BasicSolver completely to make sure the were no issues in it and also separated the instantiation from the push_back to help show that push_back is where the problem is occurring.
InformedSolver1&2 are children of BasicSolver. vector is included in BasicSolver and therefore in puzzleSolver also.
#include "stdafx.h"
#include "puzzleSolver.h"
PuzzleSolver::PuzzleSolver()
{
solvers = new vector<BasicSolver*>();
}
void PuzzleSolver::createPuzzle(string input)
{ //hitting step-over
BasicSolver* temp = new BasicSolver(input);// no errors
solvers->push_back(temp); // nullReferenceException
solvers->push_back(new InformedSolver1(input));
solvers->push_back(new InformedSolver2(input));
}
That should be all the relevant information.
Let me know if you have any ideas as to what is causing this/ how to fix it!
Thanks.
Edit:
Added BasicSolver constuctor and dependency methods by comment request
also a little background: this is a Sudoku solver for an AI class
BasicSolver::BasicSolver(string input)
{
peers = new vector<Peer*>();
squares = new vector<Square*>();
unsolved = new vector<Square*>();
solved = new vector<Square*>();
createStructure(input);
original = input;
mistakes = 0;
}
void BasicSolver::createStructure(string input)
{
try
{
createEmptyStructure(peers, squares, unsolved);
//Parse the puzzle and assign input to squares
int numCharsToRead = MAX_SQUARES; //makes sure vector isn't outside its range
if (input.length() < MAX_SQUARES) //makes sure string isn't outside its range
numCharsToRead = input.length();
for (int i = 0; i < numCharsToRead; i++)
{
if(input[i] != '.')
insertValue(input[i], (*squares)[i], unsolved);
}
}
catch(exception e)
{
throw e;
}
}
void BasicSolver::createEmptyStructure(vector<Peer*> *workingPeers, vector<Square*> *workingSquares, vector<Square*> *workingUnsolved)
{
for (int i = 0; i < MAX_PEERS; i++)
{
workingPeers->push_back(new Peer());
}
for (int i = 0; i < 81; i++)
{
try
{
workingSquares->push_back(new Square('.'));
//Adding the square to its corresponding peers
(*workingPeers)[i / MAX_ROWS]->addSquare((*workingSquares)[i]); //adds the square into its appropriate row of peers
(*workingPeers)[(i % MAX_ROWS) + COL_OFFSET]->addSquare((*workingSquares)[i]); //adds the square into its appropriate column of peers
int tempBoxCol = (i % MAX_ROWS) / MAX_BOX_COLS; //returns the box column (0,1,2)
if ((i / MAX_ROWS) < BOX_ROW_WIDTH) //if its box is in the first row
{
(*workingPeers)[tempBoxCol + BOX_OFFSET]->addSquare((*workingSquares)[i]);
}
else if ((i / MAX_ROWS) < (2 * BOX_ROW_WIDTH)) //if its box is in the second row
{
(*workingPeers)[BOX_ROW_WIDTH + tempBoxCol + BOX_OFFSET]->addSquare((*workingSquares)[i]);
}
else //if the box is in the third row
{
(*workingPeers)[2 * BOX_ROW_WIDTH + tempBoxCol + BOX_OFFSET]->addSquare((*workingSquares)[i]);
}
}
catch(exception e)
{
throw e;
}
}
*workingUnsolved = *workingSquares;
}
Edit2:
Personal tests
add these lines:
vector<BasicSolver*>* test = new vector<BasicSolver*>();
test->push_back(temp);
before
solvers->push_back(temp);
and they execute fine, I also notice that during runtime solvers is listed as outside of scope even though it is a protected variable of BasicSolver.
The problem was that the calling source did not have PuzzleSolver properly instantiated.
Thanks to #TheDark for suggesting I check that!

Set pointer to element in vector to null, then check whether pointer is null (C++)

I would like to set pointers to some elements in my vector array to NULL (based on a criteria), and then check whether an element pointer is NULL. If the pointer pointing that element is NULL, I remove the element from my vector array.
My compiler is giving me an error, saying that the address expression must be an lvalue or function designator and I do not understand why (line location commented in code). Since I am taking the address of the value using &, am I not seeing if the pointer pointing to that element is NULL?
I included the preceding code as the error may lie there,
Relevant code:
vector<particle> pl = c.particlelist;
vector<particle> noncollision = c.particlelist;
vector<vector<particle>> collisionlist = new vector<vector<particle>>();
for (int i = 0; i < c.numparticles-1; i++){
particle first = pl[i];
for (int j = i+1; j < c.numparticles; j++)
{
particle second = pl[j];
double d = distance(first, second);
if (d==0)
{
vector<particle> temp = {pl[i], pl[j]};
collisionlist.push_back(temp);
noncollision[i].setxposint(NULL);
noncollision[j].setxposint(NULL);
}
else
{
}
}
}
int j = 0;
for (int i = 0; i < noncollision.size(); i++)
{
if (&(noncollision[i].getxpos()) == NULL) ////// ERROR HERE
{
noncollision.erase(noncollision.begin()+i);
}
else
{
j++;
}
}
I am new to C++, and if you could suggest a more elegant way to do this, or a fix, it would be much appreciated. I also assume that my method of setting the pointer to an element, noncollision[i].setxposint(NULL); is correct? Can I return an integer using a function, and take the address?
Functions for getxpos and setxposint:
int particle::getxpos(){
return xpos;
}
void particle::setxposint(int b){
xpos = b;
}
You're using & to take a pointer to a temporary vale (the return from getxpos) which isn't allowed; since a temporary will be going away, the address won't be useful in any way so the language doesn't allow it. It certainly wouldn't ever be NULL even if you could get its address.
noncollision[i].setxposint(NULL);
All that line is doing is setting xpos to zero. Generally the term NULL is used with pointers, and 0 is used with things like integers. NULL is usually a macro for 0L anyway.
&(noncollision[i].getxpos()) == NULL
What this is doing, which is incorrect, is attempting to take the address of the return value from the member method getxpos() and compare it to NULL. Whereas what you really want to do is simply see if the function returns zero. So simply change this line to:
noncollision[i].getxpos() == 0
I'll explain why the compiler doesn't understand what you mean.
When you write
&(someFunction())
you are asking for the address of the thing that the function returns. But functions return values. A value doesn't have an address. Variables have addresses.
When something is a word of memory (which will contain a value), it can be used as an lvalue (left-value), because you can put things into that word of memory:
int b = 1; //make room for an `int` on the stack, then put a `1` there.
When something is just a value, it can only ever be used as an rvalue. The following would not compile, for the same reason that your code would not:
int b; //make room for an `int` on the stack.
42 = b; //ERROR, this makes no sense.
if (42 == NULL) { std::cout << "this is never true" << std::endl; }
&42; //ERROR, 42 isn't a piece of memory, it's a value.
(Caveat: you can use values to refer to words in memory: this usage is called a pointer, e.g.
int b = 1;
*((int *)(42)) = b;
meaning "put the value of b into the memory which has the address 42. This compiles fine (but crashes if you're not allowed to write to the memory at 42.)
It looks to me you're trying to keep track of 'visited' items, not sure exactly in which way.
Instead of "modifying" the items, you could use an "external" mark. A set looks to be fine here. You could use a set of iterators into the particle list, or in this case a set of indices (i,j) which will likely be more stable.
Here's a start:
#include <vector>
#include <set>
struct particle { };
double distance(particle const&, particle const&) { return 1.0; }
struct context
{
std::size_t numparticles;
std::vector<particle> particlelist;
context() : numparticles(100), particlelist(numparticles) {}
};
static context c;
int main()
{
using std::vector;
using std::size_t;
vector<particle> pl = c.particlelist;
vector<vector<particle>> collisionlist;
std::set<size_t> collision;
for(size_t i = 0; i < c.numparticles-1; i++)
{
particle first = pl[i];
for(size_t j = i+1; j < c.numparticles; j++)
{
particle second = pl[j];
double d = distance(first, second);
if(d < 0.0001)
{
collisionlist.push_back({pl[i], pl[j]});
collision.insert(i);
collision.insert(j);
}
else
{
}
}
}
for(size_t i = 0; i < pl.size(); i++)
{
if(collision.end() != collision.find(i))
{
// do something
}
}
// alternatively
for (int index : collision)
{
particle& p = pl[index];
// do something
}
}
NOTE Be very very wary of floating point comparison like
if (d==0.0) // uhoh
because it will likely not do what you expect
How dangerous is it to compare floating point values?
What is the most effective way for float and double comparison?
Is floating-point == ever OK?
It seems that you are trying to check pairs of points for collisions. You then record for each point whether it has any collision. This is best handled by a simple list of flags:
std::vector<bool> has_collision(c.numparticles, false); // init: no collisions found
Afterwards:
if (d==0)
{
has_collision[i] = true;
has_collision[j] = true;
}
At the end, iterate over the list of flags and get the points that have no collisions:
for (size_t i = 0; i < c.numparticles; ++i)
{
if (!has_collision[i])
{
// whatever
// possibly push_back pl[i] into some list
}
}
In addition: using a vector to hold a pair (i,j) of points is confusing. Standard library has the std::pair type for purposes such as this.
Also: you don't need explicit dynamic allocation (new); let Standard Library manage memory for you in a safe, non-confusing way. Instead of
vector<vector<particle>> collisionlist = *new vector<vector<particle>>();
Use
vector<vector<particle>> collisionlist;
(or vector<pair<particle, particle>>, as described above).

Segmentation fault in recursive function returning list

I have a recursive function, that is returning a list of structs.
struct Neighbour_node{
int index;
double dist;
};
And here is the function:
list<Neighbour_node> findNewNeighbours(int original, int particle, int k){
Neighbour_node node;
list<Neighbour_node> neighbours;
list<Neighbour_node> temp_neighbours;
list<Neighbour_node>::iterator iterator;
if (k <= 0){
if (particle == -1){
node.index = -1;
node.dist = 1000.0;
}
else{
node.index = particle;
node.dist = glm::length(hair[original].position - hair[particle].position);
neighbours.push_back(node);
}
}
else {
for (unsigned int i = 0; i < hair[particle].neighbours.size(); i++){
temp_neighbours = findNewNeighbours(original,hair[particle].neighbours[i],k - 1);
temp_neighbours.sort(compareNeighbour_node);
neighbours.merge(temp_neighbours,compareNeighbour_node);
}
}
return neighbours;
}
Line:
temp_neighbours = findNewNeighbours(original,hair[particle].neighbours[i],k - 1);
causes segmentation fault and I am not sure why. I have seen examples with line similar to my erroneous one and it seems, it is not wrong. But those functions were not recursive, so I am guessing that this is where the problem is - besides, when k = 0 (only one call of a function - thus as if it wasn't recursive), then it doesn't crash. Can anyone, please, help me with this?
Thanks
Check the stack size in your os.
ulimit -s
I suggest that it is because of stack.
Becase the stack you need seems increase rapidly.
Show your "hair" for more detail for us to see.