Consider this function:
bool RemoveElement(const T2& e2)
{
bool match = false;
for (int i = 0; i < _trenutno; i++)
{
if (*_elementi2[i] == e2){
match = true;
for (int j = i; j < _trenutno - 1; j++)
{
_elementi1[j] = _elementi1[j + 1];
_elementi2[j] = _elementi2[j + 1];
// SOLUTION: The two lines above are not correct.
// Instead of assigning addresses, I should have assigned
// values, ie. dereference them like below:
// *_elementi1[j] = *_elementi1[j + 1];
// *_elementi2[j] = *_elementi2[j + 1];
}
}
}
if (match)
{
_trenutno--;
//delete _elementi1[_trenutno];
_elementi1[_trenutno] = nullptr;
//delete _elementi2[_trenutno];
_elementi2[_trenutno] = nullptr;
}
return match;
}
FYI, the pointers themselves (see below). I'm trying in the above function delete values behind this particular pair of pointers (last element) using delete
because otherwise I believe memory leak would occur?
template<class T1, class T2, int max>
class Kolekcija
{
T1* _elementi1[max];
T2* _elementi2[max];
int _trenutno;
public:
Kolekcija()
{
for (int i = 0; i < max; i++)
{
_elementi1[i] = nullptr;
_elementi2[i] = nullptr;
}
_trenutno = 0;
}
// ...
~Kolekcija()
{
for (int i = 0; i < _trenutno; i++){
delete _elementi1[i]; _elementi1[i] = nullptr;
delete _elementi2[i]; _elementi2[i] = nullptr;
}
}
// ....
Why is this happening, I'd like to learn more and better understand pointers.
If your class is the data owner
and you want to remove some element:
(_elementi1[nFound] == searchValue)
delete _elementi1[nFound];
nullptr
_elementi1[nFound] = nullptr;
This sequence will protect you against memory leaks in Remove
method.
Destructor will clean other heap allocated values (assuming _trenutno
is actual count
):
for (int i = 0; i < _trenutno; i++)
{
delete _elementi1[i]; _elementi1[i] = nullptr;
delete _elementi2[i]; _elementi2[i] = nullptr;
}
Deleting nullptr
is safe
.
So my version of Remove()
:
bool RemoveElement(const T2& e2)
{
for (int i = 0; i < _trenutno; i++)
{
if (*_elementi2[i] == e2)
{
delete _elementi1[i];
_elementi1[i] = nullptr;
delete _elementi2[i];
_elementi2[i] = nullptr;
for (int j = i; j < _trenutno - 1; j++)
{
_elementi1[j] = _elementi1[j + 1];
_elementi2[j] = _elementi2[j + 1];
}
_trenutno--;
return true; //found
}
}
return false; //not found
}
I'm assuming that your collection is the data owner
. So you have to
delete
all pointers that was passed to it.
Simple example (we'r adding 3 values):
int* elements[max] = {0};
elements[0] = new int(4); //0x00FF1F
elements[1] = new int(5); //0x00FF2F
elements[2] = new int(6); //0x00FF3F
_trenutno = 3;
We have to delete
all 3 int*
If no Remove
was called destructor will handle it (delete from 0
to 2
).
If we call Remove(5)
:
5
value i == 1
delete elements[1]
that means releaze memory at address 0x00FF2F
elements[1] = elements[2]
Now our array is:
elements[0]; //0x00FF1F
elements[1]; //0x00FF3F
elements[2]; //0x00FF3F
And _trenutno = 2;
So destructor will remove pointers from '0' to '1'.
That is all 3 pointers where deleted!