C++ 저장공간 개념 | C++ 자습서 17

C++ 저장공간 (storage)

C++ 저장공간은 메모리(Memory)를 말합니다. 저장공간을 크게 분류하면 자동 공간(Auto Storage), 정적 공간(Static Storage), 동적 공간(Dynamic Storage)로 나눌 수 있습니다.

다소 개념적이지만 자료를 메모리에 어떻게 저장하느냐는 문제는 계속 다루게 될 것입니다.

하나씩 알아보겠습니다.

자동 공간(Auto Storage)

자동 공간의 변수들은 함수 안에서 정의되고 함수가 종료하면 해제됩니다.

함수의 블록 { } 안에서 선언하면 자동변수가 됩니다. 아래 예제에서 int count 가 int i 가 자동변수입니다. i는 for 문의 초기화로 for문 안에서만 유효합니다.

이 함수의 호출이 종료되고 제어권이 호출자로 다시 돌아가면 메모리는 해제됩니다. 함수는 스택(Stack) 메모리에 저장됩니다. 프로그램이 실행하면 메모리를 목적에 따라 나눕니다. 스택, 힙, 코드, 데이터 영역에 맞춰서 저장하는 것입니다.

void showSomething() {

    int count = 0;
    for (int i = 0; i < 5; i++)
    {
        std::cout << count++ << std::endl;
    }
}

비주얼 스튜디오의 디버거에서 메모리를 덤프하면 정확하게 스택을 어떻게 저장하는지 볼 수도 있습니다. 그러니까 메모리 구조가 뜬구름 잡는게 아니라 실제적인 것으로 이해할 수 있습니다.

여러번 강조하지만 메모리에 대하여 머리속에 이미지 모델을 가지고 있어야 C++이 수월해집니다. 머리속의 이미지를 코드로 구현하는 느낌으로 만들어야지 코드만 읽다보면 지쳐버립니다.

역시 스택의 장점은 함수가 종료하면 바로 메모리를 반환하기 때문에 공간 활용이 좋습니다. 메모리를 아껴야 하는 작업이라면 스택을 활용할 수 있습니다.

또 비주얼스튜디오 스택 메모리의 기본값은 1메가입니다. 스택을 많이 사용하는 재귀함수를 너무 많이 돌리면 메모리 부족 현상을 겪을 수도 있습니다. (늘릴 수 있으나 C++은 대용량 프로세스를 처리하기 위해 힙 메모리를 사용함)

정적 공간(static storage)

정적 공간은 프로그램 시작부터 끝까지 존재하는 공간입니다. 정적 변수, static 변수라고 하는 변수의 정체는 프로그램 시작부터 끝까지 메모리에 남아있습니다.

한번 static 영역에 올려놓으면 접근 시간은 빠르지만 반면 공간 효율성은 좋지 않습니다. 본통 프로그램 내내 사용해야 하는 상수나 인스턴스가 필요없는 static 메소드와 함께 사용합니다.

정적 공간에 변수를 저장하기 전에는 이게 과연 프로그램의 끝까지 남아있을 필요가 있는 것인지, 또는 용량을 많이 차지하는게 아닌지 따져 볼 필요가 있습니다.

동적 공간(dynamic storage)

동적 공간은 가장 메모리 공간이 넓고 유연한 메모리입니다.

C++프로그래머는 new 와 delete 키워드를 사용해서 메모리를 할당하고 해제시킬 수 있습니다. 이들은 힙메모리(Heap Memory) 공간에 올라가는데요. C++은 동적 공간을 프로그래머가 직접 관리해야 합니다.

직접 메모리를 관리한다고 해서 unmanaged(언매니지드 – 관리가 안된) 언어라고 합니다. 같은 OOP언어인 자바는 JVM(자바 가상 머신)이라는 기능이 있어서 프로그래머는 객체를 할당만 하고 해제는 GC(가비지 컬렉션)가 알아서 합니다.

이 부분이 C++를 배울 때 자바보다 더 깊이가 필요한 이유입니다. 메모리를 할당만 하고 해제를 안하다간 아무리 요즘 메모리가 기가 단위라 해도 금방 메모리 유출이 됩니다(Memory Leak)

아래 예제는 new 와 delete를 사용하는 예제입니다. 항상 new로 할당한 메모리는 delete 로 마무리하는 습관이 좋습니다.

#include <iostream>

class myClass {
public:
    int id;
    std::string name;
};

int main()
{
    myClass *m1 = new myClass();
    m1->id = 1001;
    m1->name = "MEE YOUNG";

    std::cout << m1->id << std::endl;
    std::cout << m1->name << std::endl;

    delete[] m1;
    return 0;

}

아마 동적 변수가 사용하는 힙메모리의 관리가 C++ 프로그래머에게는 가장 중요한 일중 하나가 아닐까 싶습니다. 가상머신이 있는 자바같은 메모리 관리에 신경쓰지 않아도 되는데요.

C++의 경우 메모리 관리를 잘할 수 있다면 매우 좋은 성능을 낼 수 있습니다.

요약

C++ 저장공간이라는 다소 개념적인 내용을 설명해봤습니다.

메모리를 어떻게 사용하는지, 시스템은 메모리를 어떻게 바라보고 있는지를 아는 것은 입체적인 사고를 갖게 합니다. 메모리가 왜 어려운가? 생각해보면 메모리를 실제로 본 사람은 없습니다. 컴퓨터회로 안에 존재하는 것이기 때문입니다.

이를 활용하기 위한 방법은 우리 머리속에서 메모리의 모델을 만들어 보는 것 입니다. 거창한게 아니라 간단한 구조 부터 상상을 하는 것 입니다. 현재 변수는 몇 바이트의 공간을 사용하고 있으며 인덱스는 어떻게 정리되어 있는가.

스택 메모리는 어떻게 크기가 줄어들고 늘어나는가? 디테일하게 알고 있는게 중요합니다. 구글의 영문 인터넷에는 이에 대해 설명이 잘된 포스팅이 많습니다.

이런 일을 도움 받기 위해서 찾아보면 아직도 한글 문서가 많이 없습니다.

정리가 잘된 영문 자료들은 많습니다. Java나 C++의 메모리 설명 문서들을 보면 유사한 부분이 있는데요. 초급자라면 스택과 힙에 대한 개념을 세우는게 중요합니다.

참고문서

Stack vs Heap Memory Allocation – GeeksforGeeks

Stack vs Heap: Know the Difference (guru99.com)

Stack vs Heap Memory in C++ – YouTube

Leave a Comment