본문 바로가기

problem solving

c++ stl vector 원소를 참조할 때 주의할 점

  Ant& current_ant = ants[current_ant_id];

경쟁 프로그래밍 문제나 코테 문제를 풀 때 주력 언어로 C++를 사용하고 있다. (현업에서는 거의 사용을 안해서 모던 C++는 잘 모른다.)

최근에 비교적 간단한 문제를 풀던 중 왜맞틀의 함정에 걸려 고생을 했는데 vector를 잘 못 사용하고 있었다는 것을 깨달아서 노트를 남긴다.

 

문제가 된 코드

vector<Ant> ants;
...

void create_new_ant_and_add_follow() {
  ...
  Ant& current_ant = ants[current_ant_id];
  ...

  Ant new_ant = createNewAnt();
  int new_ant_id = ants.size();
  ants.push_back(new_ant);
  current_ant.followers.push_back(new_ant_id)
  ...
}

개미 배열에서 현재 개미를 찾는다. 새로운 개미를 만들어서 개미 배열에 추가하고, 앞에서 찾은 개미의 팔로워 리스트에 추가하는 간단한 코드다. 언뜻 보면 잘못된 점이 잘 안 보이는데 심각한 문제가 있다.

  Ant& current_ant = ants[current_ant_id];

이 코드는 현재 개미를 개미 배열에서 찾아 참조형태로 기억을 한다.

  ants.push_back(new_ant);

이 코드는 새로운 개미를 개미 배열에 추가를 하고,

  current_ant.followers.push_back(new_ant_id)

앞서 기억한 개미 참조를 통해 팔로워 리스트에 추가를 한다.

 

새로운 개미를 개미 배열에 추가할 때, vector의 capacity를 넘어서게 되면 relocation이 발생한다. 이때 앞서 기억해 놓은 참조 변수는 더 이상 내가 원하는 개미를 참조하지 않는다.

 

교훈

stl collection의 relocation이 발생할 수 있는 operation 전후로 collection의 특정 원소를 레퍼런스나 포인터로 참조하면 혼쭐날 수 있다.

'problem solving' 카테고리의 다른 글

BOJ 1019 책 페이지  (0) 2022.04.12
BOJ 10775 공항  (0) 2022.04.10
BOJ 12858 Range GCD  (0) 2022.02.27
BOJ 1031 스타대결  (0) 2022.02.26
BOJ 24231 해석  (0) 2022.02.20