글 목록으로 돌아가기

프로그래밍 언어 / C언어

pintos를 위한 c언어 강의

[강의 요약] C언어의 심장: 포인터와 메모리 관리 완벽 정리 안녕하세요! 오늘은 프로그래밍의 '근본'이라 불리는 C언어, 그중에서도 많은 학습자가 어려워하지만 반드시 넘어야 할 산인 메모리와 포인터 에 대해 정리해 보겠습니다. 파이썬처럼 친절한 언어

임재환
임재환 2026년 4월 8일 · 2분 읽기 · 수정 2026년 4월 8일
pintos를 위한 c언어 강의

[강의 요약] C언어의 심장: 포인터와 메모리 관리 완벽 정리

안녕하세요! 오늘은 프로그래밍의 '근본'이라 불리는 C언어, 그중에서도 많은 학습자가 어려워하지만 반드시 넘어야 할 산인 메모리와 포인터에 대해 정리해 보겠습니다. 파이썬처럼 친절한 언어와 C언어는 무엇이 다른지, 왜 우리가 직접 메모리를 만져야 하는지 핵심만 짚어드릴게요.


1. C언어는 왜 '불친절'할까? (vs Python)

파이썬이 모든 것을 알아서 해주는 '자동 자가용'이라면, C언어는 운전자가 엔진 노즐 하나하나를 조절해야 하는 '수동 레이싱카'와 같습니다.

  • 하드웨어 제어: CPU와 메모리를 직접 컨트롤하기 때문에 성능이 강력합니다.
  • 명시적 타입: 모든 데이터의 크기를 프로그래머가 직접 결정해야 합니다.
  • 불친절한 에러: 잘못된 메모리에 접근하면 친절한 설명 대신 Segmentation Fault와 함께 프로그램이 종료됩니다.

2. 변수를 바라보는 새로운 시각: 주소, 값, 그리고 크기

C언어에서 변수는 단순히 값을 담는 그릇이 아니라, 메모리 상의 특정 위치를 가리키는 별명(Symbol)입니다.

  • 주소(&a): 메모리 어디에 있는가?
  • 값(a): 그 위치에 무엇이 들어있는가?
  • 크기(sizeof): 그 위치부터 몇 바이트를 사용하는가?

💡 중요 팁: C언어에서 데이터 타입(int, long 등)의 크기는 시스템마다 다를 수 있습니다. 따라서 이식성 있는 코드를 위해 stdint.h의 고정 너비 타입(int32_t, int64_t)을 사용하는 습관이 좋습니다.


3. 통곡의 벽, '포인터(Pointer)' 제대로 이해하기

포인터는 어렵지 않습니다. "주소를 저장하는 변수"일 뿐입니다.

  • 역참조(*): 포인터가 가리키는 주소로 '직접 찾아가서' 값을 읽거나 쓰는 행위입니다.
  • 포인터 타입의 비밀: int*char*는 주소 값 자체의 크기(64비트 기준 8바이트)는 같지만, 찾아갔을 때 몇 바이트를 읽어야 할지를 결정합니다.
  • 포인터 연산: p + 1은 주소 값에 1을 더하는 게 아니라, 가리키는 타입의 크기만큼 건너뛰는 것을 의미합니다.

4. 메모리 관리의 핵심: 힙(Heap)과 동적 할당

함수가 종료되면 사라지는 지역 변수(Stack)와 달리, 프로그램 실행 중에 원하는 만큼 메모리를 쓰고 싶을 때 힙(Heap) 영역을 사용합니다.

  • malloc: 메모리 빌려오기. (반환 타입이 void*이므로 적절한 형변환이 필요합니다.)
  • free: 빌린 메모리 반납하기.
  • 메모리 누수(Memory Leak): 빌려놓고 반납(free)하지 않으면 시스템의 메모리가 고갈됩니다. "malloc과 free는 항상 짝꿍"임을 잊지 마세요!

5. 구조체(Struct)와 메모리 정렬의 마법

서로 다른 타입을 묶는 구조체에는 숨겨진 원리가 있습니다. 바로 패딩(Padding)입니다.

CPU는 메모리 접근 효율을 위해 데이터를 특정 단위로 정렬합니다. 이 과정에서 빈 공간(Padding)이 생겨, 실제 구조체 크기가 멤버들의 합보다 커질 수 있습니다.

  • 최적화 팁: 크기가 큰 타입부터 작은 타입 순서로 멤버를 선언하면 패딩을 줄여 메모리를 아낄 수 있습니다.

✅ 오늘 강의의 핵심 '코딩 습관' 5가지

  1. sizeof 생활화: 타입 크기를 짐작하지 말고 항상 sizeof()로 확인하세요.
  2. 포인터 초기화: 선언과 동시에 NULL이나 유효한 주소로 초기화하세요.
  3. 중괄호({}) 생략 금지: if/for문 뒤에 코드가 한 줄이라도 중괄호를 쓰는 것이 안전합니다.
  4. 우선순위는 괄호로: 연산자 우선순위가 헷갈릴 땐 무조건 ()를 쓰세요.
  5. 문자열 끝은 \0: C언어 문자열은 마지막 널 문자를 위한 1바이트가 더 필요함을 명심하세요.