Code 영역
프로세스가 실행할 코드와 매크로 상수가 기계어의 형태로 저장된 공간이다. 컴파일 타임에 결정되고 중간에 코드를 바꿀 수 없게 Read-Only 로 지정돼있다.
Data 영역
코드에서 선언한 전역변수 또는 static 변수 등등이 저장된 공간이다. 전역변수/static 값을 참조한 코드는 컴파일 하고 나면 Data 영역의 주소값을 가르키도록 바뀐다. 실행 중도에 전역변수가 변경 될 수도 있으니 이 영역은 Read-Write로 지정돼있다.
단, 초기화 되지 않는 전역 변수는 BSS 영역에 할당된다.
Stack 영역 (스택)
1) 매개변수, 지역변수 - 함수
2) 함수호출 할당, 함수호출끝 해제
3) 공간이 작다(보통 1mb)
4) 크기가 컴파일 타임에 정해진다.
자료구조로 많이 알려진 Stack은 프로세스의 메모리 공간을 관리하기 위한 알고리즘중 하나이다. 이 영역은 함수 안에서 선언된 지역변수, 매개변수, 리턴값, 돌아올 주소 등등이 저장되고 함수 호출시 기록하고 종료되면 제거한다. 기록하고 종료하는 메커니즘은 자료구조에서 배운 후위선출(LIFO) 방식을 따른다.
스택의 크기는 약 1MB이며, 컴파일 타임에 크기가 결정되기 때문에 무한히 할당 할 수 없다. 재귀함수가 너무 깊게 호출되거나 함수가 지역변수를 너무 많이 가지고 있어 stack 영역을 초과하면 stack overflow 에러가 발생한다.
ex) V2
Heap 영역
1) 사용자의 동적할당
2) 할당과 해제는 프로그래머가 직접 해야 한다.
3) 공간이 비교적 크다(32bit 최대 4GB-모든 프로그램)
4) 크기는 런타임에 정해진다.
프로그래머가 필요할 때마다 사용하는 메모리 영역. Code, Data, Stack 영역과는 다르게 Heap은 런타임에 결정된다. 프로그래머는 malloc, calloc으로 Heap 영역의 메모리를 사용할 수 있다. 데이터 배열의 크기가 확실하지 않고 변동이 있을 때 Heap 영역을 활용해서 메모리를 할당한다. 단 사용하고 난 다음에는 반드시 해제를 해야 한다. 안그러면 memory leak이 발생한다. 초창기 스마트폰을 사용할 때 위젯을 설치해서 계속 프로그램들을 종료해 주어야 했던 이유가 바로 이것 때문이다. 스택보다 할당할 수 있는 메모리 공간이 많다는 것이 장점이지만, 포인터로 메모리 영역을 접근해야 하기 때문에 다른 자료구조에 비해서 데이터를 읽고 쓰는게 느리다.
컴파일 타임과 런타임이란? (원문보기)
런타임(Runtime)과 컴파일타임(Compiletime)은 소프트3웨어 프로그램개발의 서로 다른 두 계층의 차이를 설명하기 위한 용어이다. 프로그램을 생성하기 위해 개발자는 첫째로 소스코드를 작성하고 컴파일이라는 과정을 통해 기계어코드로 변환 되어 실행 가능한 프로그램이 되며, 이러한 편집 과정을 컴파일타임(Compiletime) 이라고 부른다.
컴파일과정을 마친 프로그램은 사용자에 의해 실행되어 지며, 이러한 응용프로그램이 동작되어지는 때를 런타임(Runtime)이라고 부른다.
"런타임"과 "컴파일 타임"이라는 용어는 종종 서로다른 두 가지 타입의 에러를 나타내기 위해 사용되어지곤 하는데, 컴파일 타임 에러는 프로그램이 성공적으로 컴파일링되는 것을 방해하는 신택스에러(Syntax error)나 파일참조 오류와 같은 문제를 말하며, 이런 경우 컴파일러는 컴파일 타임 에러를 발생시키고 일반적으로 문제를 일으킨 소스코드 라인을 지시해준다.
만약, 어떤 소스코드가 이미 실행가능한 프로그램으로 컴파일 되었다 할지라도 이것은 여전히 프로그램의 실행중에 버그를 일으킬 수 있다. 예를 들자면, 예상치 못한 오류 또는 충돌로 동작하지 않을 수 있는데 이렇게 프로그램이 실행중에 발생하는 형태의 오류를 런타임오류 라고 한다.
즉, 프로그램 실행 중일 때를 런타임이라고 부르고 프로그램 빌드 등등의 작업을 할 때를 컴파일타임이라고 보면 된다.
힙과 스택의 차이점
스택은 크기를 컴파일타임에 정하기 때문에 공간의 크기가 존재하지만,
힙은 크기를 런타임에 정하기 때문에 공간의 크기가 존재하지 않는다.
예를 들어서, 이 코드를 실행시키면 빌드 오류가 뜬다.
Const int Size = 10 은 상수값을 약속하는 코드로 보면 되고
int Size2 = 10; 은 변할 수 있는 변수를 정한 것이다.
Arr[Size2] 는 빨간 줄이 그어져 있다. 그 이유는, 변수는 크기가 런타임에 정해지기 때문이다(힙).
따라서 크기를 컴파일 타임 중에 잡을 수가 없기에 빌드 오류가 뜨는 것이다.
동적할당이란?
간단하게 설명하면, 동적할당은 한정된 RAM의 메모리를 효율적으로 관리해 주기 위해서, 프로그램을 사용할 때에 할당하고 사용하지 않을 때에는 해제시켜 주는 것을 말한다. 또한 동적할당을 사용하면 함수(스택)를 리턴한 후에도 힙에 저장한 메모리는 살아 있기 때문에 유용하게 사용할 수 있다.
동적할당에 대한 더 자세한 내용은 아래 참조한 링크의 블로그에 아주 잘 설명되어 있다.
jhnyang.tistory.com/330
스택에 저장된 데이터의 경우에는 순서대로 접근해야만 한다. 하지만 힙같은 경우 데이터 용량이 훨씬 크기 때문에 순서대로 접근하는 방식으로는 비효율적이다. 따라서 우리는 주소로 접근해야 한다.
C스타일의 경우에 alloc, mellow 를 사용하고 C++의 경우에는 new type 을 사용한다. 여기서는 new type만을 다룰 것이다.
자세한 내용은 다른 포스트글에서 다루도록 하겠다.
데이터
정적변수 STATIC
vector 동적배열 : 뒤에서 삽입 삭제 유리한 구조, 중간에 삽입 삭제(insert, erase)가능은 하다, 반복자?
stl 표준 템플릿 라이브러리 - 컨테이너, 반복자(Iterator)란 무엇인가?
참조
출처: https://selfish-developer.com/entry/스택-힙-코드-데이터영역 [아는 개발자]
출처: https://spaghetti-code.tistory.com/35 [어떻게 짤것인가]
'C++ 코딩 > C++ 기초개념' 카테고리의 다른 글
<C++ 기초> 식과 연산자, 연산자의 종류와 우선순위 (0) | 2021.02.23 |
---|---|
<C++ 기초> 동적배열, sti vector, 멤버함수 (0) | 2021.02.18 |
<C++ 기초> typedef, 열거형 enum (0) | 2021.02.16 |
<C++ 기초> 문자열 조작하기 -char[], string (0) | 2021.02.15 |
<C++ 기초> 메모리 동적 확보, 배열의 동적인 확보 (0) | 2021.02.14 |
<C++ 기초> 변수와 스코프(지역변수와 전역변수) 02.14 (0) | 2021.02.14 |
<C++ 기초> 배열에 대한 이해, 문자열과 배열, char 02.08 (0) | 2021.02.08 |
<C++ 기초> 포인터와 레퍼런스(* , &) 02.04 (0) | 2021.02.04 |