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 |