stdremove not working correctly, still has extra elements
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
std::remove surprises many C++ developers the first time they print a container after calling it. The algorithm seems to "leave extra elements behind," but the real issue is that std::remove does not erase anything from the container; it only rearranges the range and returns a new logical end.
What std::remove Actually Does
The algorithm works on iterators, not on containers. It scans the range, keeps the values that should stay, moves them toward the front, and then returns an iterator pointing just past the last kept element.
Consider this example:
The output shows the kept values at the front, but values.size() remains unchanged. The elements after newEnd are still present in the vector storage. They are valid objects, but their values are unspecified for normal business logic and should be ignored.
That is why printing the whole vector after std::remove makes it look as though the function failed.
Use the Erase-Remove Idiom
To really shrink a container such as std::vector, combine std::remove with the container’s erase member function:
This pattern is known as the erase-remove idiom. First, std::remove partitions the values you want to keep. Then erase deletes the unwanted tail from the container and updates the size.
The same idea works with std::remove_if when the removal condition is a predicate:
This removes every even number and leaves the vector with only odd values.
Know When Container Members Are Better
Sequence containers that store elements contiguously, such as std::vector and std::string, commonly use the erase-remove idiom. Other containers offer their own removal operations that are often more direct.
For std::list, prefer the member function:
Using the member function is clearer because the container already knows how to unlink nodes efficiently. The generic algorithm is most useful when you are working with iterator-based ranges or containers that do not provide a special member.
A good rule is simple: if you are using std::remove, always ask yourself whether you still need to call erase.
Common Pitfalls
The classic mistake is printing or iterating all the way to container.end() after std::remove. The meaningful range ends at the iterator returned by the algorithm, not at the original container size.
Another common issue is assuming std::remove can work on associative containers such as std::set or std::map. Those containers do not support the same kind of element movement through mutable value assignment, so the erase-remove idiom is aimed at sequence-like containers.
Developers also sometimes forget that removing values from a vector can invalidate iterators and references after the erase call. If you stored positions into the container earlier, recompute them after the erase step.
Finally, the algorithm name itself causes confusion. remove sounds destructive, but in the standard library it really means "move the values to keep and report the new end." Once that mental model is clear, the behavior stops being surprising.
Summary
- '
std::removedoes not shrink a container; it returns a new logical end.' - Use the erase-remove idiom to truly delete elements from vectors and similar containers.
- '
std::remove_ifapplies the same pattern with a predicate.' - Prefer container-specific members such as
list::removewhen they exist. - Treat the range after the returned iterator as unwanted tail data until you erase it.
Related reading
- stdsort algorithms memory usage
- STL algorithm for Vector Add
- STL way to access more elements at the same time in a loop over a container
- Store the largest 5000 numbers from a stream of numbers
- stdremove with vectorerase and undefined behavior
- stdthis_threadyield vs stdthis_threadsleep_for
- stdtransform and toupper, no matching function
- Step-by-step debugging with IPython

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.