I am a beginner, and I want to delete an item from an array, non-STL.
This doesn't seem possible? Below. So, out of share curiosity, how can I delete or remove an item from a regular array, I am not using STL. I want to know how this can be done with one dynamic array that's been allocated on the HEAP.
As you'll have noticed, an array is a contiguous sequence of bytes. So you have to pretend to delete something.
Typically, you move all the higher elements one space down, overwriting the element you want to loose, and freeing up an extra space on the end.
The same happens with std::vector, except you can additionally shrink the vector to remove that last free space at the end. It happens in two steps, first shuffle everything down by one--erase, the shrink the vector--remove. See The Erase Remove Idiom. https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
Finally, shrinking a vector doesn't cause the internal array to change, just the "end" mark to change. The destructor of that last element is called (if it has one) to clean it up.
Your code, as you posted it, leaks everything. You don't need a Monsters* at all. I kept it to minimize the changes to your original code. main() should look like:
1 2 3 4 5 6 7 8 9 10 11 12
int main()
{
int size = 5;
Monsters monsters(size);
Monster* monster1 = new Monster("Sally");
Monster* monster2 = new Monster("Rich");
monsters.add(monster1);
monsters.add(monster2);
monsters.remove(monster1);
}
Ah, no worries about that. I am just trying to figure out:
How I can remove the item from array while using a pointer for loop. I read somewhere, that the pointer you pass in, must be used to point to the item you decide to remove. Not sure of how I can interpret this.
We don't recommend using raw pointers, C++ was designed to manage such things safely, and I've shown how this may be achieved above. Nevertheless, here's the remove in it's most basic form, as you've asked for it. But please please please, don't use code that looks like this in anything but a sample.
constexpr size_t Max {5};
size_t total {0};
T something [Max];
The 'something' is an array of type T objects.
1 2 3 4
// change value of something[0]
// change value of something[1]
// change value of something[2]
total = 3; // assert(total <= Max)
Now we have array with three objects. (In reality we have five, but we make believe.)
We want to remove one of them.
kbw's first example had array of pointers and the value to remove was a pointer. kbw's second example had array of Monsters and the value to remove was a Monster, whose name did match.
The question is, how do you know which monster to remove?
If we know that it is the second in array, then:
1 2 3 4 5
size_t victim = 1;
for ( size_t e = victim; e + 1 < total; ++e ) {
something[e] = something[e+1];
}
--total;
No vector. std::vector<Monster> monsters;. I have seen this. I know how to do this with STL. But, I want to know if this can be done without STL help. Like in my code above.
when @alix has said that the ordering doesn't matter. You just swap the element to be deleted with the last element and decrement the count of the number of elements. If the element is a pointer, then also delete the memory if needed.
That is what std::remove() does as it doesn't change the size. However, you don't actually need to swap here as you can adjust its size. Just copy over the element to be removed by the last element.
From previous code:
1 2 3 4 5 6 7 8 9 10
bool remove(const Employee& e)
{
for (auto ee = begin(); ee != end(); ++ee)
if (ee->getName() == e.getName()) {
*ee = employees[--current_total];
returntrue;
}
returnfalse;
}
ee is the pointer to the element to be removed. current_total is the number of elements. First decrement current_total (--current_total) and then copy the last element over the removed element ( *ee = employees[--current_total] )
It depends upon what you want the previous last element to be. Either as it was and use = (in which case both the removed element and the last element are the same), or the removed element and use std::swap().