---
description: 프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간(RAM)은 다음과 같다.
---

# 메모리 구조를 알아보자

## **1. 메모리 구조**

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/posts-memory_structure_1.png)

프로그램이 운영체제로부터 할당받는 대표적인 **메모리 공간(RAM)**&#xC740; 다음과 같다.

### **1.1. 코드(code) 영역**

실행할 프로그램의 코드가 저장되는 영역.

* 텍스트 영역이라고도 부른다.
* 프로그램이 시작하고 끝날 때까지 메모리에 계속 남아있는다.
* 당연히 컴파일 된 기계어가 들어게 된다.
* CPU는
* 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.

### **1.2. 데이터(data) 영역**

프로그램의 전역 변수와 정적(Static) 변수, 문자열 상수가 저장되는 영역.

* 프로그램이 시작하고 끝날 때까지 메모리에 계속 남아있는다.

### **1.3. 스택(Stack) 영역**

함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역.

* 함수의 호출과 함께 할당되며 함수의 호출이 완료되면 소멸한다. 이렇게 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임(Stack Frame)이라고 한다.
* 프로그램이 자동으로 사용하는 임시 메모리 영역이다.
* 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.
* 컴파일 시에 크기가 결정된다.
* 윈도우는 약 1mb 크기, 리눅스는 약 8mb

**장점**

* 낭비되는 공간이 없다.
* 하나의 명령만으로 메모리 조작과 어드레스 조작이 가능하다.

**단점**

* 한계가 있어 한계를 초과하도록 삽입할 수 없다.
* 즉, 유연성이 부족하다.

### **1.4. 힙(Heap) 영역**

사용자가 직접 관리할 수 있고 해야만하는 영역.

* 힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.
* 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.
* `malloc()` 또는 `new 연산자`를 통해 할당하고 `free()` 또는 `delete 연산자`를 통해서 해제가 가능하다.
* 런타임 시에 크기가 결정된다.

**장점**

* 프로그램에 필요한 **개체의 개수**나 **크기**를 미리 알 수 없는 경우에 사용 가능.
* 개체가 너무 커서 스택 할당자에 맞지 않는 경우 사용 가능.

**단점**

* 할당 작업으로 인한 속도 저하
* 해제 작업으로 인한 속도 저하
  * 주로 병합을 사용할 때 해제 작업에 더 많은 주기가 소요된다.
*   힙 손상으로 인한 속도 저하

    응용 프로그램에서 힙 블록을 적절하게 사용하지 않을 경우 힙이 손상된다.

    가장 많이 발생할 수 있는 **힙 손상 문제**로는 이중 해제, 해제 후 블록 사용, 블록 경계를 벗어나 덮어쓰기 등이 있다.
*   힙 경합으로 인한 속도 저하

    두 개 이상의 쓰레드에서 동시에 데이터에 액세스하려고 하면 경합이 발생하여 한 쪽 쓰레드의 작업이 완료되어야 다른 쪽 쓰레드의 작업이 진행될 수 있다.

    이 문제는 현재 **다중 프로세서 시스템**에서 일어나는 문제 중 가장 큰 문제다.

    경합은 일반적으로 쓰레드와 프로세스의 **컨텍스트 스위칭**을 가져온다. 컨텍스트 스위칭에도 리소스가 많이 소모되지만 프로세서 캐시에서 데이터가 손실되어 나중에 해당 쓰레드가 다시 살아날 때 이 데이터를 다시 작성하는 데에 리소스가 훨씬 많이 소모된다.

## **2. Stack vs Heap**

Stack 영역이 클 수록 Heap 영역이 작아지고 Heap 영역이 클 수록 Stack 영역이 작아진다.

스택 할당 속도와 힙 할당 속도를 비교해보자.

결론부터 말하자면 스택이 훨씬 빠르다. 스택은 이미 할당 되어있는 공간을 사용하는 것이고 힙은 사용자가 따로 할당해서 사용하는 공간이다. 다만 스택은 공간이 매우 적기 때문에 모든 응용에서 스택을 사용할 수 는 없다.

좀 더 자세히 알아보면,

**스택**에서 **할당**의 의미는 이미 생성되어 있는 스택에 대해 **포인터의 위치**만 바꿔주는 단순한 **CPU Instruction**(덧셈과 뺄셈 연산, 일반적으로 단일 Instruction)이다.

반면 **힙**에서의 **할당**은 요청된 chunk의 크기, 현재 메모리의 fragmentation 상황 등 **다양한 요소**를 고려하기 때무에 더 많은 **CPU Instruction**이 필요하다.

## **3. 오버플로우(Overflow)**

Stack의 지역변수는 사용되고 소멸하기 때문에 데이터 용량의 불확실성을 가진다. 따라서 Stack 영역에서의 주소값은 밑에서부터 채워지며 그 다음 주소는 선언된 순서대로 정해진다. 반면 Heap 영역에서의 주소값은 위에서부터 채워 내려지기 때문에, 두 메모리 영역의 주소가 겹치게 되는 Overflow가 발생할 수도 있게 된다.

### **Heap overflow**

Heap이 위에서부터 주소값을 채워져 내려오다가 Stack영역을 침범하는 경우.

### **Stack overflow**

Stack영역이 Heap을 침범하는 경우.

## 4. malloc으로 메모리를 할당해주는 이유

* malloc없이 새로운 노드를 만들게 되면, ft\_newlst 함수가 종료되면서 반환되는 new 노드는 stack에서 사라지게 된다.
* malloc을 하면 힙영역에 할당되고, 그래야 함수가 종료돼도 메모리 상에 남아 `t_list *new` 가 할당 받은 메모리를 가리킬 수 있게 된다.
