독학/백준

블랙잭 풀다가 배운 것들

CodingGalaxy 2026. 3. 23. 14:26

🚀 [C언어/디버깅] 3중 루프 알고리즘부터 메모리 패딩까지 하루 만에 부수기

알고리즘 문제를 풀다가 발생한 사소한 `break` 오류를 시작으로, CLion 디버거를 활용해 컴퓨터의 메모리 구조까지 뜯어본 하루의 기록.

1. 알고리즘: 다중 루프 탈출과 정렬의 활용

  • 문제 상황: 큰 수부터 내림차순 정렬된 배열에서 합이 M 이하인 최대 3개의 수를 찾아야 함.
  • 핵심 깨달음: break의 위치가 중요! 조건을 만족했을 때 가장 안쪽 루프만 탈출하면 제대로 된 최댓값을 찾을 수 없음.
  • 해결책 (Flag 변수): int found = 0;을 사용하여 정확히 M을 찾은 순간 모든 루프를 연쇄적으로 종료시킴.
  • 내림차순의 마법: sum <= M을 만족하는 첫 순간이 그 조합의 최댓값이므로 더 작은 수는 탐색할 필요가 없음 (가지치기).

2. CLion 디버거 (Debugger) 200% 활용법

printf 노가다는 이제 그만! 프로그램의 뼈대를 엑스레이처럼 들여다보는 방법.

  • Breakpoint (빨간 점): 코드 좌측 여백을 클릭해 프로그램이 멈출 지점을 지정.
  • Variables 탭: 현재 변수에 들어있는 값, 배열의 상태를 실시간으로 확인.
  • Step Over (F8): 코드를 한 줄씩 실행하며 변수의 변화를 눈으로 추적. 로직의 구멍(예: 의도치 않은 루프 탈출)을 잡는 데 최고.

3. 메모리 뷰 (Memory View)와 리틀 엔디언

변수가 실제 RAM에 어떻게 16진수로 저장되는지 눈으로 확인하기.

  • 접근법: Variables 창에서 변수 우클릭 후 Show in Memory View 선택.
  • 자료형의 크기: char는 1바이트(1칸), int는 4바이트(4칸), double은 8바이트(8칸)를 차지함.
  • 리틀 엔디언 (Little Endian): 10진수 13은 16진수로 0d. 하지만 메모리에는 역순인 0d 00 00 00으로 저장됨 (현대 CPU의 특징).
  • 포인터 연산의 비밀: p + 1을 할 때 실제 주소는 자료형의 크기만큼 증가함 (int는 +4, double은 +8).

4. 충격의 구조체 패딩 (Structure Padding)

1바이트(char) + 4바이트(int) = 5바이트? NO! 정답은 8바이트.

  • 메모리 정렬 (Memory Alignment): CPU는 데이터를 4바이트나 8바이트 단위로 뭉텅이로 읽어오는 것을 좋아함.
  • 패딩 (Padding): char 뒤에 int가 오면, int를 4의 배수 주소에 맞추기 위해 컴퓨터가 강제로 3바이트의 빈 공간(00)을 끼워 넣음.
  • 메모리 공간을 조금 낭비하더라도 CPU의 처리 속도를 높이기 위한 하드웨어적인 설계 방식!

 

 

C언어에서는 int는 4바이트, char는 1바이트지만 실제로 잡아먹고 있는 메모리가 놀랍게도 8바이트다! 사실상 여기서 버리는 메모리 3바이트라는 것을 알 수 있다.