본문 바로가기
IVS/C 프로그래밍

[C] 메모리 관련

by 코곰_ 2025. 1. 13.

 

C 언어에서 메모리는 프로그램 실행 중 데이터를 저장하고 관리하기 위해 여러 메모리 영역으로 나뉜다. 각각의 영역은 특정 유형의 데이터와 목적에 따라 구분된다.

 

아래와 같은 순서를 따른다.

+-----------------------+ <- 높은 주소
|      힙 (Heap)        | (동적 메모리 할당, 아래로 성장)
|-----------------------|
|      빈 영역          | (힙과 스택 사이의 여유 공간)
|-----------------------|
|      스택 (Stack)     | (함수 호출 시 자동 할당, 위로 성장)
|-----------------------|
|      BSS 영역         | (초기화되지 않은 전역/정적 변수)
|-----------------------|
| 초기화된 데이터 영역   | (초기화된 전역/정적 변수)
|-----------------------|
|      코드 (Code)      | (프로그램 명령어)
+-----------------------+ <- 낮은 주소

 

 

 

 

 

1. 코드(Code) 영역

 

  • 설명:
    • 실행할 프로그램의 코드(명령어)가 저장되는 영역.
    • 기계어 형태로 저장되어 프로세서가 직접 실행한다.
  • 특징:
    • 읽기 전용: 코드가 수정되지 않도록 보호.
    • 프로그램이 시작될 때 메모리에 로드되며, 종료될 때 해제된다.

 

void myFunction() { /* 이 함수의 명령어가 코드 영역에 저장됩니다 */ }

 

 

 

2. 데이터(Data) 영역

  • 설명:
    • 프로그램에서 전역 변수정적 변수가 저장되는 영역.
    • 초기화된 전역/정적 변수초기화되지 않은 전역/정적 변수로 나뉜다.
  • 구분:
    • 초기화된 데이터 영역:
      • 명시적으로 초기화된 전역 변수 및 정적 변수가 저장됨.
      • 프로그램 시작 시 초기 값으로 설정.
    • BSS(Block Started by Symbol) 영역:
      • 초기화되지 않은 전역 변수와 정적 변수가 저장됨.
      • 자동으로 0으로 초기화됩니다.
  • 생명 주기:
    • 프로그램 실행 중 지속적으로 유지된다.
int global_var = 10;     // 초기화된 데이터 영역
static int static_var;   // BSS 영역 (자동 0 초기화)

 

 

 

3. 스택(Stack) 영역

  • 설명:
    • 함수 호출 시 지역 변수, 매개변수, 반환 주소 등이 저장되는 영역.
    • LIFO(Last In, First Out) 구조로 메모리가 할당 및 해제된다.
  • 특징:
    • 자동으로 할당 및 해제되므로 빠르고 효율적.
    • 제한된 크기를 가지며, 초과할 경우 스택 오버플로우가 발생.
    • 함수가 호출되면 메모리가 할당되고, 종료되면 해제된다.
void myFunction() {
    int local_var = 5; // 스택에 저장
}

 

 

4. 힙(Heap) 영역

  • 설명:
    • 실행 중에 동적으로 할당된 메모리가 저장되는 영역.
    • 사용자가 직접 malloc, calloc, realloc, free를 사용하여 메모리를 관리한다.
  • 특징:
    • 메모리 크기를 유동적으로 조정할 수 있음.
    • 할당한 메모리를 명시적으로 해제하지 않으면 메모리 누수(Memory Leak)가 발생.
    • 속도가 상대적으로 느리며, 관리가 복잡.
int* ptr = (int*)malloc(sizeof(int) * 10); // 힙에 동적 메모리 할당
free(ptr); // 할당 해제

 

 

5. 상수(Constant) 영역

  • 설명:
    • 문자열 상수const 키워드로 선언된 변수들이 저장되는 영역.
  • 특징:
    • 읽기 전용이며 수정할 수 없음.
    • 상수 문자열은 프로그램 종료 시까지 유지된다.
const int num = 100;     // 상수 영역에 저장
char* str = "Hello";     // 문자열 상수가 상수 영역에 저장

 

 

 

 

 


~수정중~
1. Const 변수는 어디에 있을까?

ROM(ram이 부족한데 값을 변경하지 않을 때)
2. 초기화 된 전역변수는 어디에?

ROM

3. 초기화 된 전역변수 값은 어디서 불러오는걸까?
4. 초기화 안된 전역 변수는 어디에?
5. 0으로 초기화 하는것과, 초기화 하지 않는 전역변수는 어떠한 차이가 있을까?

 

전역변수 = ram

rom은 바이트/ 비트단위로 접근하여 값을 지우고 저장할 수 있다.

 

포인터는 주소값이므로 항상 동일한 데이터 크기를 가진다(자료형과 무관하게)

 

 

함수 

 

샷시등은 안전상의 문제로 heap영역 사용 X

 

Stack

- 80%이상 공간이 넘지 않도록 설계

User stack

 

R stack

 

 

#include <stdio.h>
void modifyValue(int *ptr) { // 함수의 파라미터도 지역변수 
    int tempvalue = 10;
    *ptr = tempvalue; // pointer를 사용하여 num값을 변경 
}
int main() {
    int num = 5;
    printf("변경 전: %d\n", num); 
    modifyValue(&num); // 함수에 값을 전달
    printf("변경 후: %d\n", num);
    return 0;
}

 

 

 

 

 

call by reference

- 주소값을 넘겨줌

- 값에 대한 오염이 생길 수 있다. (넘겼는데 값을 변경하는 등)

 

이를 해결하기 위해? const 변수

const변수로 값을 변경하는 걸 막는 건, 컴파일러가. 

 

(page: 0 ~ 256 byte)

 

 

 

Q. stack size를 어떻게 측정할까?

- 스택을 사용하면 값이 오염된다

Q. stack overflow를 어떻게 감지할까?(70% 이상)