Why am I leaking memory here (depth first search) c++? - c++

int Solver::negamax(Position* pos,int alpha,int beta, int color, int depth ) {
if(depth==0 || is_final(pos)){
return evaluate(pos);
}
else{
vector < Position* > moves = generate_moves(pos->get_board());
vector < Position* >::iterator move;
int min = 99999;
for(move = moves.begin(); move < moves.end(); move++){
int val = negamax(*move,alpha, beta, -color, depth - 1 );
if(val <= min){
min = val;
delete best;
best = NULL;
best = (*move)->get_board();
}
else{
delete *move; //So this isnt cleaning up?
*move = NULL;
}
}
min = -min;
return min;
}
}
vector < Position* > TakeAwaySolver::generate_moves(Board *brd){
TakeAwayBoard *board = static_cast<TakeAwayBoard*>(brd);
vector < Position* > moves;
if(board->get_data() >= 3){
TakeAwayBoard *b = new TakeAwayBoard(board->get_data() - 3);
Position* p = new Position(b);
moves.push_back(p);
}
if(board->get_data() >= 2){
TakeAwayBoard *b = new TakeAwayBoard(board->get_data() - 2);
Position* p = new Position(b);
moves.push_back(p);
}
TakeAwayBoard *b = new TakeAwayBoard(board->get_data() - 1);
Position* p = new Position(b);
moves.push_back(p);
return moves;
}
I valgrinded my program and I'm apparently leaking memory. It seems that I'm deleting all unused objects, but perhaps I'm not understanding something. generate_moves() does allocate memory for each of the objects being pushed in. Evaluate returns 1. Does it seem possible that I'm leaking memory in any location?

You have an if/else in which *move is only deleted in one of the paths. I'd check there.
for(move = moves.begin(); move < moves.end(); move++){
int val = negamax(*move,alpha, beta, -color, depth - 1 );
if(val <= min){
min = val;
delete best;
best = NULL;
best = (*move)->get_board();
//best is deleted, but *move is not
}
else{
delete *move;
*move = NULL;
}
}

A std::vector<position *> container will not automatically delete the inserted elements when it is destroyed. Make it a std::vector<x<position *> > where x is some suitable smart pointer template, like auto_ptr.
If you don't want to do that, then the next best thing is to wrap the vector in a class whose destructor iterates over the vector and calls delete on every pointer.
I.e. this is a memory leak:
{
std::vector<int *> vec;
vec.push_back(new int[3]);
// vec goes out of scope
}
Sure, the vector cleans itself up! It deletes its internal array, etc. But it does nothing with the new int[3] that we allocated and put into the vector.

It seems to me that you never clear the 'minimum' positions.
You store a pointer to the board in best, and take care to clear that when you replace it with a better minimum, and in case the move isn't a minimum so far, you properly clean it up, but you never clean the actual position pointer in case it's a minimum.
As a side note, this is redundant:
best = NULL;
best = (*move)->get_board();

Related

Delete Zero in ArrayList in C++

Inside the ArrayList I'm trying to delete all possible 0's that are appended as input, but for now it only deletes just one 0, no matter where it is located. But seems like I can't delete more than one zero at the time. How can I fix this?
void AList::elimZeros(){
int i;
int curr = 0;
for(i=0; i < listSize; i++) {
if ( (listArray[i] != 0 ) && (curr<listSize) ){
listArray[curr] = listArray[i];
curr++;
}
else if (listArray[i] == 0 )
{
listArray[curr] = listArray[i+1];
listSize--;
curr++;
}
}
}
This is the class for the ADT
class AList : public List {
private:
ListItemType* listArray; // Array holding list elements
static const int DEFAULT_SIZE = 10; // Default size
int maxSize; // Maximum size of list
int listSize; // Current # of list items
int curr; // Position of current element
// Duplicates the size of the array pointed to by listArray
// and update the value of maxSize.
void resize();
public:
// Constructors
// Create a new list object with maximum size "size"
AList(int size = DEFAULT_SIZE) : listSize(0), curr(0) {
maxSize = size;
listArray = new ListItemType[size]; // Create listArray
}
~AList(); // destructor to remove array
This is the input I'm testing with:
int main() {
AList L(10);
AList L2(20);
L.append(10);
expect(L.to_string()=="<|10>");
L.append(20);
expect(L.to_string()=="<|10,20>");
L.append(30);
L.append(0);
L.append(40);
L.append(0);
L.append(0);
expect(L.to_string()=="<|10,20,30,0,40>");
L.elimZeros();
expect(L.to_string()=="<|10,20,30,40>");
assertionReport();
}
It'd be helpful if you posted the class code for AList. Think you confused Java's ArrayList type, but assuming you're using vectors you can always just do:
for (int i = 0; i < listSize; i++) {
if(listArray[i] == 0) listArray.erase(i);
}
EDIT: Assuming this is the template of for the AList class, then there is simply a remove() function. In terms of your code, there are two issues.
You reference listSize in the for loop, then decrement it inside of the loop. Each iteration evaluates the value separately so you're reducing the number of total loop iterations and stopping early.
The other thing is if the entry is zero you shouldn't increment curr and set listArray[curr] = listArray[i+1]. This is basically assuming the next entry will not be a zero. So if it is, then you're copying the element and moving to the next. Your if statement can be cleaned up with:
if (listArray[i] == 0) {
listSize--;
} else {
listArray[curr] = listArray[i];
curr++;
}

Heap corruption detected in C++ on delete[] array after copying it

I'm trying to create a method that create a sort of a dynamic array: when the index exceedes it creates another array with one more element and then it deletes the old one copying the pointer of the new one in the old one. But when I delete the old array I have an HEAP CORRUPTION DETECTED and the program freezes. states is the old array (with 10 items) initializationIndex is used to keep track of the array length.
if (states == nullptr)
states = new int[10];
if (initializationIndex > 10) {
int *tempArr = new int[initializationIndex];
arrayCpy(states, tempArr, initializationIndex - 1);
delete[] states; // HEAP CORRUPTION DETECTED
states = tempArr;
}
if (arrayContains(initializationIndex, states, stateToInsert))
return false;
states[initializationIndex] = stateToInsert;
initializationIndex++;
The function arrayCpy:
void arrayCpy(int * src, int * dst, int offset)
{
int i = 0;
for (i = 0; i < offset; i++) {
dst[i] = src[i];
}
}
you edited the question.
if (states == nullptr)
states = new int[10];
if (initializationIndex > 10) {
int *tempArr = new int[initializationIndex];
arrayCpy(states, tempArr, initializationIndex - 1);
delete[] states; // HEAP CORRUPTION DETECTED
states = tempArr;
}
lets assume initializationIndex = 15, you are doing copy for 14 elements while states size is only 10
delete[] tempArr; // HEAP CORRUPTION DETECTED
states = tempArr;
you delete the array and then use it.
as people said in comments, use std::vector, no need to do new/delete.

Memory leak with lists c++

The idea of the function is to divide the original list in X Lists all gather in a single array without delete nor creating new Cells.
The function do his job great but when I check the leaks with valgrind or Dr. Memory, It appears to have some leak problems...
List* function (List & todivide, int t = 2){
Cell* aux = todivide.l; // l is the head of the list
int tam = (todivide.size()/t == 0) ? todivide.size()/t : todivide.size()/t+1;
List* arrayoflists = new List [tam];
for(int i = 0, k = 0; aux != 0; i++){
if(i%t == 0){
arrayoflists[k].l = aux;
aux = aux->sig;
k++;
}
if(i%t == t-1){
Cell* p = aux->sig;
aux->sig = 0;
aux = p;
}
}
l.l = 0;
return arrayoflists;
}
I see nothing wrong... Any ideas?
Thanks in advance
There's nothing wrong inside the function but since you're returning a pointer that you created using new, you might be forgetting to delete the returned pointer where ever you're using it outside the function.

C++ malloc() memory corruption(fast)

I am fairly new to programming and am having memory issues with my program. Somewhere I am overusing memory, but can't find the source. I don't understand why it is giving me issues with malloc allocation as i don't dynamically allocate any variables. Thanks
//returns the index of the character in the string
int find(string line, int begin, int end, char character) {
for (int i = begin; i <= end; i++) {
if (line[i] == character) {
return i;
}
}
//return -1 if not found
return -1;
}
//Get the characters from levelorder that align with inorder
char* getCharacters(char inOrder[], char levelOrder[], int a, int b) {
char *newLevelOrder = new char[a];
int j = 0;
for (int i = 0; i <= b; i++)
if (find(inOrder, 0, a-1, levelOrder[i]) != -1)
newLevelOrder[j] = levelOrder[i], j++;
return newLevelOrder;
}
//creates a new Node given a character
Node* newNode(char character) {
Node *node = new Node;
node->character = character;
node->left = NULL;
node->right = NULL;
return node;
}
//creates the huffman tree from inorder and levelorder
Node* createInLevelTree(char inOrder[], char levelOrder[], int beginning, int end, int size) {
//if start index is out of range
if (beginning > end) {
return NULL;
}
//the head of the tree is the 1st item in level order's traversal
Node *head = newNode(levelOrder[0]);
//if there are no children we can't go farther down
if (beginning == end) {
return head;
}
//get the index of the node
int index = find(inOrder, beginning, end, head->character);
//get the subtree on the left
char *leftTree = getCharacters(inOrder, levelOrder, index, size);
//get the subtree on the right
char *rightTree = getCharacters(inOrder + index + 1, levelOrder, size-index-1, size);
//branch off to the left and right
head->left = createInLevelTree(inOrder, leftTree, beginning, index-1, size);
head->right = createInLevelTree(inOrder, rightTree, index+1, end, size);
//delete
delete [] leftTree;
delete [] rightTree;
return head;
}
Fixed with this line. Thanks Sam.
Char* new level order = new char [b]
Somewhere I am overusing memory, but can't find the source.
I'd suggest you at least replace your character arrays with std::vector<char> or std::string and put some size assertions in, or use the at member to see no over-indexing happens. Furthermore, using operator new more than likely is implemented in terms of malloc, and operator delete in terms of free. Therefore you are allocated dynamically.
Also, wiki for RAII. Try and employ RAII for dynamically allocated memory ... always. std::vector and std::string gives you this for free.
Also, consider the code below:
char* getCharacters(char inOrder[], char levelOrder[], int a, int b) {
char *newLevelOrder = new char[a];
int j = 0;
for (int i = 0; i <= b; i++)
if (find(inOrder, 0, a-1, levelOrder[i]) != -1)
newLevelOrder[j] = levelOrder[i], j++;
return newLevelOrder;
}
Reading this, I'm not sure of the quantity of b. There is no restriction imposed at the call sight. How do I know that the for loop won't invoke indefined behavior (by overindexing). Typically a correct for loop would use "a" here, as "a" was used to create the array... If you want to code like this, use asserts liberally, as you are making assumptions about the calling code (but just use a vector....).
char *newLevelOrder = new char[a];
int j = 0;
for (int i = 0; (i < a) && (i <= b); i++)
{
or
assert (b < a);
char *newLevelOrder = new char[a];
int j = 0;
for (int i = 0; (i <= b); i++)
{
I leave the task of replacing your arrays with vectors and string as an exercise for you, as well as liberally spraying asserts in for loops mentioned... That will likely solve your problems

When to delete class pointer from array

I have a list of pointer object *lst[200];
I use this to add one to it:
object a = new object();
a->id = current_amount;
lst[current_amount] = a;
current_amount++;
now I want to add a function delete it:
I simply want to remove this element from array: (I store an id use it to delete it)
void delete(object *elem)
{
if(!elem)
return;
for (int i = elem->id ; i < current_amount - 1;i++)
{
lst[i] = lst[i + 1];
}
}
Question: When to call delete elem? The code above doesn't free the memory at all...
void deleteElem(object *elem) // you can't call your function 'delete'
{
if(!elem)
return;
for (int i = elem->id ; i < current_amount - 1;i++)
{
lst[i] = lst[i + 1];
}
delete elem; // this free's the memory
}
Since the code above isn't C++, here's some that is:
std::list<std::unique_ptr<object>> lst;
and the methods erase, push_back, push_front.