1 분 소요

  • 에 동적으로 메모리에 할당한 것은 명시적으로 소멸시켜라.
  • 스택에 생성된 변수는 유효 범위가 종료되면 자동 소멸 된다.

개요

메모리 구조를 알아두면, 초기화예외 처리등 C++ 동작 원리를 이해할 수 있어 많은 도움이 됩니다.

프로그램을 실행하면 각 코드 요소는 하기 구조에 맞춰 메모리에 로딩됩니다.

항목 읽기/쓰기 내용
코드(텍스트) 세그먼트 읽기 프로그램 코드, 제어문, 리터럴, 함수
데이터 세그먼트(BSS, Block Started by Single) 읽기/쓰기 초기화 안된(혹은 0으로 초기화된) 전역 변수 또는 정적 변수
데이터 세그먼트(rodata, read only data) 읽기 문자열 상수
데이터 세그먼트(data) 읽기/쓰기 0 이외의 값으로 초기화된 전역 변수 또는 정적 변수
(Heap) 세그먼트 읽기/쓰기 new 등으로 생성한 동적 메모리. 명시적으로 소멸시켜야 함
스택(Stack) 세그먼트 읽기/쓰기 함수의 지역 변수, 인자, 리턴값등. 자동 소멸됨

image

코드 세그먼트

코드 세그먼트는 프로그램 코드, 제어문, 리터럴, 함수등이 저장되며 읽기 전용입니다.

데이터 세그먼트

데이터 세그먼트는 3개(BSS, rodata, data)로 나뉘어 있습니다. 전역 변수, 정적 전역 변수, 정적 멤버 변수, 함수내 정적 지역 변수는 BSS 영역과 data 영역에 저장됩니다.

  • BSS 영역은 0으로 초기화해야 할 것들이 모여 있습니다. 이렇게 한곳에 모여 있기에 일괄로 0으로 초기화 하여 시스템 성능을 향상 시킬 수 있습니다.

  • data 영역은 개별적으로 초기화할 항목이 모여 있습니다.

  • rodata 영역은 문자열 상수만 특별히 모아둔 영역입니다. 일반적으로 상수(const int a = 10;의 표현에서 10)들은 코드 세그먼트 영역에 있지만, 문자열은 용량이 좀 되기 때문에 별도로 rodata 영역에 두고 이를 포인터 등으로 참조하여 사용합니다. 또한, 중복된 문자열을 코드 여기저기에서 정의하더라도, 컴파일러가 용량 최적화를 하면서 알아서 1개로 취합해 줍니다.

new로 할당한 동적 메모리 영역입니다. delete로 명시적으로 소멸시키지 않으면, 계속 메모리를 차지하고 있는데요,이런 메모리 릭이 조금씩 쌓이다 보면 결국 프로그램 메모리가 부족해서 종료될 수 있습니다. 그러니 꼭 delete 하셔야 합니다.

1
2
3
int* p = new int;
...
delete p; // new로 생성한 것은 반드시 delete

스택 보다 메모리 할당 속도가 훨씬 느립니다.

스택

스택함수내의 지역 변수, 인자, 리턴값이 호출될때마다 차곡 차곡 쌓이는 공간입니다.

함수 호출이 종료되거나 유효 범위가 종료되었다면 자동으로 소멸됩니다. 이러한 자동 소멸은 향후 스마트 포인터(auto_ptr, unique_ptr, shared_ptr)나 Holder의 개념으로 많이 활용되니 잘 알아 두시기 바랍니다.

하기 호출 과정에서의 스택의 상황을 개념적으로 도식화하면 다음과 같습니다.

1
2
3
4
5
6
7
8
int f1(int a) {
    int b = 10;
    return f2(a, b);
}
int f2(int a, int b) {
    int c = 20;
    return a + b + c;
}

image

댓글남기기