링버퍼, 2002

@codemaru · October 21, 2011 · 3 min read

링버퍼란 원형큐의 또다른 이름이라 생각할 수 있다. 뒤로 삽입이 이루어지고, 앞으로 삭제가 이루어지며 최대 갯수를 넘어설 경우 앞에 있는 것이 자동적으로 삭제되고 뒤에 추가가 이루어 진다. 요즘 흔히 사용하는 휴대전화기의 문자 메시지의 원리를 생각하면 된다. 최대 저장갯수가 초과하게 되면 가장 오래된 메시지가 삭제되고 새로운 메시지가 보관되는 원리아다. 물론 그렇게 처리가 되지 않은 구식 전화기도 종종있다.

이러한 큐를 구현하는데 가장 많이 사용되는 방법중에 하나가 읽기, 쓰기 포인터를 이용한 방법이다. 각각은 MAXDATA가 되게 되면 다시 0으로 초기화 되어야 하므로 주로 나머지 연산자를 이용해서 많이들 구현하게 된다. 일반적으로 사용되는 수식은 대부분 아래와 같다.

#define MAXDATA 200 

int nPos = (nPos + 1) % MAXDATA; 

흔히들 사용하는 진부한 식이다. 물론 이러한 수식을 처음 보는 분들께서는 위의 식에서 nPos가 움직이는 값을 관찰하면 금방 0~MAXDATA-1을 반복하면서 변화하게 되리란 것을 알수 있을것이다.

몇일전 필자는 위와 같은 형태의 자료구조를 가진 것을 한번 만들 일이 있어서 프로그램을 작성한 일이 있었다. 하지만 작성도중 정말 어처구니 없는 일을 당하고 말았다.

#define MAXDATA 3600 * 200 

int nPos = (nPos + 1) % MAXDATA; 

아무래도 이상한 결과가 출력되어 추적해 본 결과 nPos값이 0에서 200으로 변하는 것이 아닌가… ㅋㅋ… 이쯤 되었으면 아! 하는 분들이 많이 계시리라는 생각이 든다. 괄호가 빠져서 그런 결과가 나왔던 것이다. 하지만 실제로 선언과 참조가 한참이 분리된 코드에서는 그렇게 쉽게 생각나는 내용이 아니어서 한번 적어 보았다. 참고로 위 코드의 제대로 된 버전은 아래와 같이 되어야 한다.

#define MAXDATA (3600 * 200) 

int nPos = (nPos + 1) % MAXDATA;
@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중