최근에 알고리즘 분석이라는 학부 과제로 레드블랙트리를 만들으라는 내용이 제출되었었습니다.
거기서 트리의 노드를 이런식으로 구성했는데요
struct RBNODE{
...
RBNODE* parent;
RBNODE* Right;
RBNODE* Left;
...
};
아시다싶이 레드블랙트리가 2가지의 scheme 을 가지고 밸런싱을 하잖아요
그중 하나인 reconstruct 에서 문제가 발생했습니다.
회전을 하는데 , 맨 꼭대기에 위치할 놈의 Left child 가 되어야 할 놈을 Right child에 붙인 것이죠.
그래서 한참을 헤맸습니다. 몇일을 헤맨것 같아요.
심지어 테스트 자료로 주어진 input 의 특성에 의해 특정 방향으로만 회전이 일어났던 것이고
저는 그걸 보고 "왜 루트를 낀 회전이 일어나면 이전 루트가 사라지는걸까" 하고 생각해버린 것이죠.
그래서 루트를 안전하게 이동시킬 방법만 계속 수정했지만, 될리 있나요. 그래서 계속 헤메이다가
마지막 방법으로 친구에게 reconstruct 부분 코드만 보여줬는데,
위에서 말씀드렸던 잘못된 child 지정을 문제삼더군요. 그제서야 보니 정말 잘못되있더라고요 (아마 그 당시에는 피로에 착각을 했던 것인지)
물론 지금은 버그 픽스도 다 되어서 아주 큰 데이터에도 문제가 일어나지 않게 되었습니다. 한마디로 과제 종결이죠.
그런데, 이렇게 육안으로 잘 보이지 않는 포인터 연산 오류는 어떻게들 대처하시나요?
특별히 디버그 모드를 이용하시는 전략(?) 이 있으시다면 여쭈어봐도 될까요.
포인터에 어떠한 값을 올바르게 넣었는지 컴퓨터는 알 수가 없으니 결국 확인은 작업자가 해줘야 합니다.
다만, 그 노가다를 어떻게하면 효율적으로 할 수 있는지가 관건이죠.
가능하면 작업이 완료된 시점이 아니라 작업 중간중간 테스트 유닛을 만들어 활용하면 실수할 확률이 줄어들겠죠.
저같은 경우엔 해당 기능에 관련된 변수들을 가장 마지막단계의 변수들부터 출력시켜 값을 봅니다.
그리고 거기서 이상한 값이 나오는 변수에 관여하는 변수들을 찍어보고...
그러다보면 결국 어디서 값이 엉킨건지 찾을수 있더라고요.