C++ - 메모리 구조

rizz·2024년 1월 22일
0

C

목록 보기
25/25

📒 메모리 구조

📌 프로그램 동작 원리

  1. 사용자가 운영체제를 통해 프로그램 실행을 요청한다.
  2. 하드디스크에 저장되어 있던 프로그램을 작동시키기 위해 메모리의 프로그램 코드 영역에 올린다.
  3. CPU는 프로그램 코드를 읽어 호출규약(Calling Convention)에 의해 메모리를 관리하고 명령문을 실행한다.
  4. 프로그램 실행을 위해 동적 메모리가 할당되면 Free Store 영역을 사용하게 된다.
  5. 시스템이 작동하기 위해 CPU가 임시적인 정보를 스택에 저장하게 되면 Free Store 영역을 사용하게 된다.
    Free Store가 부족할 땐, Heap에서는 메모리를 할당하지 않고(NULL), Stack에서는 Stack Overflow가 발생하게 된다.

📌 메모리 구조

📌 Kernel 영역

  • 하나의 프로세스에 할당되는 총 메모리 공간 중에서 유저 영역을 제외한 나머지 영역이며, 운영체제라는 하나의 소프트웨어를 실행시키기 위해서 필요한 메모리 영역
  • 사용자 코드는 이 영역에서 읽거나 쓸 수 없다.
  • 단일 영역으로 커널 모드를 사용하는 모든 프로세스에서 공유된다.
  • 시스템 운영에 필수적이기 때문에 페이지 파일보다 RAM에 존재한다.

📌 Text(Code) 영역

  • 사용자가 작성한 코드가 기계어로 저장되는 영역
  • Text 영역에 저장된 명령어들을 CPU가 하나씩 가져가 처리한다.
  • Read-Only
  • 라이프 타임 : 프로그램 시작 ~ 프로그램 종료

📌 Data 영역

  • 초기화된 전역 변수와 정적 변수가 저장되는 영역
  • 프로그램 실행 시, 전역 변수와 정적 변수는 메인 함수가 호출되기 전에 데이터 영역에 할당된다.
  • 라이프 타임 : 프로그램 시작 ~ 프로그램 종료
  • 초기화된 Read-Only(ROM) 영역과 초기화된 Read-Write(RAM) 영역으로 더 세분화할 수 있다.
  • 예를 들어,
char s[] = "hello world";
int debug = 1;

위 코드는 초기화된 Read-Write 영역에 저장된다.

const char* str = "hello world";
  • 위 코드는 상수 문자열 리터럴 "hello world"의 첫 번째 문자를 가리키는 문자 포인터 변수(str)를 정의하였다.
  • 이 경우 문자열 리터럴 "hellow world"는 초기화된 Read-Only 영역에 저장되고 문자 포인터 변수(str)는 초기화된 Read-Write 영역에 저장된다(런타임에 수정될 수 있기 때문).
  • 마찬가지로
static int i = 10;

위 코드 또한 Read-Wirte 영역에 저장된다.

📌 BSS 영역

  • 초기화되지 않은 전역 변수와 정적 변수가 저장되는 영역
  • 초기화되지 않은 Data 영역을 나타내기도 하며, 'Block Started by Symbol'을 의미하는 고대 어셈블러 연산자의 이름을 따서 명명되었다.
  • 이 영역의 데이터는 프로그램이 실행되기 전에 OS 커널에 의해 0으로 초기화된다.
  • 초기화를 안 할 경우 문제가 생길 수 있기 때문에 존재한다.
  • Read-Write
// .bss
int a;

// .data
int b = 0;

// .rodata
const int c = 0;

void main() {
	// stack
    const int d = 0;
}
  • 단, C++ 표준에서 꼭 const를 .rodata에 저장된다는 말이 없다. 따라서 컴파일 하기 나름인 것 같다.

📌 Stack 영역

  • 프로그램에서 함수 호출에 필요한 모든 데이터가 저장되는 영역
  • 함수 호출을 위해 푸시된 값 세트는 'Stack Frame'이라고 명명되고, 모든 자동 변수(함수의 지역 변수와 매개 변수 포함)와 호출자의 변수로 구성된다.
  • LIFO(Lsat In First Out) 구조
  • 메모리의 높은 주소부터 낮은 주소로 할당된다. (일부 아키텍처는 반대일 수 있음)
  • 컴파일 시점에 크기가 결정된다.
  • MSVC의 글에 따르면 x86 및 x64의 경우 1MB라고 한다.
  • 라이프 타임 : 필드 시작 ~ 필드 종료

📌 Heap 영역

  • 동적 메모리 할당이 발생하는 영역
  • 런타임에만 크기를 알 수 있고 프로그램 실행 전에 컴파일러가 정적이지 않은 변수에 대해 프로그래머가 요청한 메모리를 할당하는 영역
  • BSS 영역의 끝에서 시작하여 높은 메모리 주소 쪽으로 증가한다.
  • malloc / new, free / delete에 의해 관리된다.
  • 라이프 타임 : 프로그래머에 의해 생성되고 삭제된다.

📌 상수(Constant)

  • 필드 밖에서 선언된 상수 : Data 영역에 저장
  • 필드 안에서 선언된 상수 : Stack 영역에 저장
  • 필드 안에서 선언된 상수 문자열 : Data 영역에 저장

📌 매크로 상수(Macro Constant) / 열겨체(Enumeration)

  • 매크로 상수 : #define은 전처리 과정에서 치환되므로 메모리 공간에 할당되지 않는다.
  • 열거체 : 정숫값에 식별자를 부여한 형태이고, 매크로 상수처럼 치환되기 때문에 메모리 공간에 할당되지 않는다.
profile
복습하기 위해 쓰는 글

0개의 댓글

관련 채용 정보