<etc>/두고 두고 활용하는 개발 노트 !

#1 - C++ 컨테이너에서 remove 함수와 erase 메소드를 함께 사용해야 하는 이유 !

Rizingblare 2023. 4. 2. 16:37
  • 1. 브리핑
    • 일시 : 2023-03-29 (Wen)
    • 상황 : 23-1 C++프로그래밍 강의 Lab
    • 관련 기술: C++, <algorithm>
  • 2. 내용
    • intro:
      • C++ 강의에서 진행하는 Lab을 수행하다가 문제를 마주했다. 총 6문제가 나왔는데 이 문제만 올바른 출력을 못냈다. 그냥 대충 `cout`으로 출력만 똑같이 해서 답만 맞출걸 하는 생각이 이제 떠오른다.
      • C++ STL vector 컨테이너에 저장된 요소들 중에서 quantity가 0에 해당하는 값들만 remove_if 함수로 지우는 것이 문제의 요구사항 중 하나였다.
      • 그래서 remove_if 함수에 vector 컨테이너의 `.begin()`과 `.end()` iterator, Item a의 quantity가 0이면 return하는 lambda 함수를 파라미터로 넘겨주었다.
      • 잘 지워지는 듯 싶더니 마지막에 계속 쓸데없는 값들이 남는다. 입력값으로 미루어짐작해 보면 후반부 입력값들이 뒤에서부터 차례로 남아있는 것 같은데, 도저히 영문을 알 수 없다.
      • [사진]
      • 뒤늦게 교수님 몰래 웹 서핑으로 해결해보려 했지만 너무 늦게 결심한터라 결국 시간 안에 해결하지 못했다.
    • detail:
      • 원인을 분석해본 결과 <algorithm> 라이브러리의 remove와 remove_if 함수는 해당하는 내용을 완전히 제거해주는 함수가 아니라고 한다.
      • 다른 컨테이너의 `.remove()` 메서드나 `.erase()` 메서드는 실제로 요소들을 삭제하지만
      • Algorithm의 remove 함수는 지워야 할 요소를 발견하면 그 뒤의 요소들을 하나씩 앞으로 이동시키는 방식이 사용된다고 한다.
      • 그래서 실제 컨테이너의 크기가 줄어드는 것이 아니란다. 원래 삭제되었다면 삭제된 개수만큼 크기가 줄어야 하는데 그렇지 않다는 점! 즉, 완전 삭제라고 볼 수 없다.
      • 이런 특성 때문에 STL Container의 `.erase()` 메서드와 조합해서 많이 사용된다고 함.
      • 그렇게 실행된 remove 함수는 지우고 남은 잔여 데이터들이 시작되는 iterator를 리턴한다. 그래서 다음고 같이 컨테이너에 `.erase()` 메소드의 파라미터로 remove함수와 컨테이너의 `.end()` iterator를 넘겨주면 비로소 실제 메모리 상에서 완전히 제거되는 코드를 구현할 수 있다.
  • 3. 참고