When to delete class pointer from array - c++

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.

Related

triggered breakpoint when trying to deallocate and recreate array dynamically

so the purpose of this code is to delete an array in order to resize it by 1 because I want to add another object to it. The issue is it triggeres a breakpoint when I delete the array.
Car& Car::operator+=(Engine e) {
if (Empty()) {
cout << "The car doesn't have a type! Engine cannot be added!" << endl;
}
else {
if (m_numEngine < 7) {
int newSize = m_numEngine + 1; // New size of array
Car* newArray = nullptr;
newArray = new Engine[newSize]; // Created temporary pointer to store old arrays info into temp one
for (int i = 0; i < m_numEngine; i++) { // Storing old into new
newArray[i] = this->engine[i];
}
newArray[newSize] = e; // Adds e's values into the last index
delete[] engine; // Deletes old array BUT TRIGGER BREAKPOINT OCCURS HERE
engine = newArray; // Stores temp array back into old array so I can return "THIS" object
}
}
return *this;
Error occurs at
"delete[] engine"
changed
newArray[newSize] = e;
to
newArray[m_numEngine++] = e;

c++ How to add value at the beginning of the array and index it?

template <class T>
void DArray<T>::add(T value){
if (currentNum==size){
size=size*2;
delete [] dArray;
}
dArray[0]=value;
currentNum++;
}
I just started to learn c++ and learning all these pointer and dynamic array stuff. Really suffering at how to add the value at the beginning of the array and make the value index to the next one such as position+1. Can anyone point out why my value did pass to only dArray [0] when I use cin but did not index to next position.
int val;
for(int i=1; i<=5; i++){
cout << "Please enter integer value number "<<i<< ": ";
cin >> val;
dInt.add(val);
dInt.printAll();
}
Creating your own container class is actually quite a hairy task. Typically most containers are implemented using global new/delete to allocate raw bytes, and then elements are added by calling placement new.
This code is untested, but should be along the right lines (ish). The code could be improved using std::move, but I'll leave that for now...
template <class T>
void DArray<T>::push_back(const T& value) {
if (currentNum == size) {
// just in case size is zero, or something like that
size = std::max(size + 2, size * 2);
// allocate memory (but don't construct objects, yet)
T* temp = ::operator new (sizeof(T) * size);
// copy construct each element
for(auto i = 0; i < currentNum; ++i)
{
// we have to use placement-new here :/
new (temp + i) T(dArray[i]);
// destroy old item
dArray[i].~T();
}
// free the old memory
::operator delete (dArray);
// update to the new array
dArray = temp;
}
// copy construct the new element
new (dArray + currentNum) T(value);
// increment the count
currentNum++;
}
Adding to the start of the array involves moving each element up in the array. As a result, it's a little bit more involved.
template <class T>
void DArray<T>::push_front(const T& value) {
if (currentNum == size) {
// just in case size is zero, or something like that
size = std::max(size + 2, size * 2);
// allocate memory (but don't construct objects, yet)
T* temp = ::operator new (sizeof(T) * size);
// copy construct each element
// this time iterate in reverse
for(auto i = 0; i < currentNum; ++i)
{
// copy old array into new array (starting at index 1)
new (temp + i + 1) T(dArray[i]);
// destroy old item
dArray[i].~T();
}
// free the old memory
::operator delete (dArray);
// update to the new array
dArray = temp;
}
else
{
// copy old elements in array (traverse in reverse order)
for(auto i = currentNum; i > 0; --i)
{
// construct new item (copying previous element)
new (dArray + i) T(dArray[i - 1]);
// call dtor on old element
dArray[i - 1].~T();
}
}
// construct first element in array
new (dArray) T(value);
// increment the count
currentNum++;
}
... and for completeness, the destructor.
template <class T>
DArray<T>::~DArray()
{
for(auto i = 0; i < currentNum; ++i)
{
// call destructor on each element
dArray[i].~T();
}
// free the memory
::operator delete (dArray);
}
This is a reason most people just end up saying "use std::vector"...

C++ destructor throws error

I have the following code:
class MyList
{
private:
public:
int* list;
int size = 0;
int max;
// constructor
MyList(int s)
{
max = s;
size = 0;
if(max > 0)
list = new int[max];
};
// destructor
~MyList()
{
for (int x = 0; x < max; x++)
delete (list + x);
};
};
I tried to clear the memory with that destructor. However, it throws an error on second iteration. What did I do wrong? Also, it wouldn't let me do it this way:
delete list[x];
Can someone explain to me why? Thank you so much.
You should use delete[] because list is created via new[]-expression. e.g.
// destructor
~MyList()
{
delete[] list;
}
Note that they must be pair; new int[max] create an array containing max's elements, delete[] destroy the whole array. delete should only be used for pointer created by new.
And better to change the constructor to
// constructor
MyList(int s)
{
max = s;
size = 0;
if(max > 0)
list = new int[max];
else
list = nullptr;
}
to make sure list is always valid.
Try this:
MyList(int s)
: max(s),
size(0),
list(new int[s])
{
};
~MyList()
{
delete[] list;
};
i dnt understand why are you using
a loop to deallocate that memory.... you should simpy write
delete[] list;
that would be enough!
in your destructor you are using delete (list(a pointer)+x) this is not deallocating memory you created...
you are tryin to delete addresses next to your list by adding value of x loop in it
i hope you understood your error :)

Expand and add a new object to a array inside a function

I'm trying to expand and add a new object to a array inside a function and have that array be effected outside the function as well (the arrays pointer is sent as a parameter).
void addMedia(Media* medias[], int &nrOfMedias, string title, int publYear, string author, int nrOfPages)
{
Media** tempArray = new Media*[nrOfMedias +1];
for(int i = 0; i < nrOfMedias; i++)
{
tempArray[i] = medias[i];
}
delete [] medias;
medias = tempArray;
delete [] tempArray;
medias[nrOfMedias] = new Book(title, publYear, author, nrOfPages);
nrOfMedias++;
}
This code works great inside the function but when I get outside it the array is still empty. As i understand this it's because the pointer is changed inside the function but how can i expand the array without having it change the pointer?
(I can not change the return data type or the parameters, assignment requirements.)
Do change medias = tempArray; to *medias = tempArray;, make it compile, polish your memory management (consider, what really should be freed, what not).
Don't view medias as an array of pointers, view it as a pointer to an array. Working example (slightly simplified):
class Media
{
public:
Media () { m_strTitle = "unknown";}
string m_strTitle;
};
class Book : public Media
{
public:
Book(string strTitle) { m_strTitle = strTitle; }
};
void addMedia(Media* medias[], int &nrOfMedias)
{
Media * tempArray = new Media[nrOfMedias +1];
for(int i = 0; i < nrOfMedias; i++)
{
tempArray[i] = (*medias)[i];
}
delete [] *medias;
(*medias) = tempArray;
(*medias)[nrOfMedias] = Book("newTitle");
nrOfMedias++;
}
int main()
{
int numMedia = 10;
Media * myArray = new Media[numMedia];
addMedia(&myArray, numMedia);
for (int i = 0; i < numMedia; i++)
{
cout << i << ") " << myArray[i].m_strTitle << endl;
}
return 0;
}
You don't need delete [] tempArray; because tempArray actually points to the same memory block as medias does after medias = tempArray;
Your function will work well whithout that line but I assume that you know what you pass with Media* medias[]

Why am I leaking memory here (depth first search) 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();