Worldscope

Vector erase() function

Palavras-chave:

Publicado em: 05/08/2025

Understanding the Vector erase() Function in C++

The std::vector::erase() function in C++ is a powerful tool for removing elements from a vector. This article provides a comprehensive overview of how to use erase(), including its syntax, behavior, and implications for performance. We'll cover the fundamental concepts, provide a code example with detailed explanations, and discuss alternative approaches and complexity analysis.

Fundamental Concepts / Prerequisites

Before diving into the erase() function, it's essential to have a basic understanding of the following concepts:

  • Vectors in C++: Vectors are dynamic arrays that can grow or shrink in size at runtime. They provide contiguous storage for elements of the same data type.
  • Iterators: Iterators are generalized pointers that allow you to traverse and access elements in a container like a vector.
  • Memory Management: Understanding how vectors manage memory is crucial as erasing elements can lead to reallocation and shifting of elements.

Core Implementation/Solution

The erase() function is used to remove elements from a vector. It comes in two forms:

  • Erase a single element: iterator erase (iterator position);
  • Erase a range of elements: iterator erase (iterator first, iterator last);

The function invalidates iterators and references to the erased elements and all elements after the erased elements. It returns an iterator pointing to the element that followed the last erased element, or vector::end() if the last element(s) of the vector were erased.


#include <iostream>
#include <vector>

int main() {
  std::vector<int> myVector = {10, 20, 30, 40, 50};

  // Erase a single element (the element at index 2, which is 30)
  auto it = myVector.erase(myVector.begin() + 2); // it now points to 40

  std::cout << "Vector after erasing element at index 2: ";
  for (int num : myVector) {
    std::cout << num << " ";
  }
  std::cout << std::endl; // Output: 10 20 40 50

  if(it != myVector.end())
    std::cout << "Iterator points to: " << *it << std::endl; // Output: Iterator points to: 40
  else
    std::cout << "Iterator points to end()" << std::endl;


  // Erase a range of elements (from index 0 up to but not including index 2)
  myVector = {10, 20, 30, 40, 50}; // Reset the vector

  myVector.erase(myVector.begin(), myVector.begin() + 2); // Erase 10 and 20

  std::cout << "Vector after erasing elements from index 0 to 1: ";
  for (int num : myVector) {
    std::cout << num << " ";
  }
  std::cout << std::endl; // Output: 30 40 50

  return 0;
}

Code Explanation

The code demonstrates two use cases of the erase() function:

First Erase (Single Element):

  • std::vector<int> myVector = {10, 20, 30, 40, 50};: Initializes a vector with some integer values.
  • auto it = myVector.erase(myVector.begin() + 2);: Erases the element at index 2 (which is the value 30). myVector.begin() + 2 creates an iterator pointing to the third element. The erase() function returns an iterator to the next valid element after the erased element. In this case, it points to the element with the value 40.
  • The code then iterates through the modified vector and prints its contents.
  • The code checks if the iterator is valid, meaning it's not pointing to the end of the vector, and prints the value the iterator points to.

Second Erase (Range of Elements):

  • myVector = {10, 20, 30, 40, 50};: Resets the vector to its initial state. This is important to demonstrate the range erase operation.
  • myVector.erase(myVector.begin(), myVector.begin() + 2);: Erases elements from the beginning of the vector up to (but not including) the element at index 2. Thus, the elements at index 0 and 1 (10 and 20) are removed.
  • The code then iterates through the modified vector and prints its contents.

Complexity Analysis

The time and space complexity of the erase() function are crucial considerations for performance-sensitive applications.

Time Complexity:

  • Single Element Erase: Erasing a single element from a vector has a time complexity of O(n) in the worst case, where n is the number of elements after the erased element. This is because all subsequent elements need to be shifted to fill the gap created by the removal.
  • Range Erase: Erasing a range of elements also has a time complexity of O(n) in the worst case, where n is the number of elements after the erased range. Similar to single element erase, subsequent elements need to be shifted to fill the gap.

Space Complexity:

  • The erase() function itself has a space complexity of O(1). It operates in place, meaning it doesn't require any additional memory proportional to the size of the vector. However, if the vector's allocated memory exceeds the new size after the elements are erased, the vector might reallocate to a smaller size. Reallocation depends on the capacity() of the vector and the implementation of the standard library. This reallocation *could* be O(n) in some situations. However, the erase function itself is still O(1) space.

Alternative Approaches

While erase() is a standard and efficient way to remove elements, other approaches exist, each with its own trade-offs.

1. std::remove and erase Idiom:

This approach is particularly useful when removing elements based on a specific condition. It uses std::remove to move all the elements that *shouldn't* be removed to the beginning of the vector, then uses erase to remove the remaining elements at the end.


#include <algorithm>
#include <vector>
#include <iostream>

int main() {
  std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

  // Remove all even numbers.
  vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x){ return x % 2 == 0; }), vec.end());

  for (int x : vec) {
    std::cout << x << " ";
  }
  std::cout << std::endl; // Output: 1 3 5 7 9
  return 0;
}

Trade-offs: This approach can be more efficient when you need to remove multiple elements based on a condition because it only shifts elements once. The lambda expression in `remove_if` provides a flexible way to define the removal condition. However, it may be slightly less readable than a simple erase in simple cases.

Conclusion

The std::vector::erase() function is a fundamental tool for managing elements in C++ vectors. Understanding its syntax, behavior, and complexity is crucial for writing efficient and reliable code. While the erase() function offers flexibility, remember to consider the performance implications of shifting elements when removing items from the middle of the vector. Alternative approaches, such as using std::remove and erase, may be more suitable for specific use cases, especially when removing elements based on complex conditions.