태그 글목록: Stack

[C++ 정리] 정적 & 동적 메모리 할당 2015-06-15

메모리가 운영되는 방식에 대한 이해를 위해 다음 그림을 보도록 하자.

memory

프로그램이 실행되고 동작하는 원리

① 사용자가 운영체제를 통해 프로그램 실행을 요청한다.
② 하드디스크에 저장되어있던 프로그램을 작동시키기 위해 메모리의 프로그램 코드 영역에 올린다.
③ CPU는 프로그램 코드를 읽어 호출규약(Calling Convention)에 의해 메모리를 관리하고 명령문들을 실행한다.
④ 프로그램 실행을 위해 동적메모리가 할당되면 FreeStore 영역을 사용하게 된다.(아래로 넓힌다.)
⑤ 시스템이 작동하기 위해 CPU가 임시적인 정보를 스택에 저장하게 되면 FreeStore 영역을 사용하게 된다.(위로 넓힌다.)
※ Heap메모리와 Stack메모리의 많은 사용으로 FreeStore영역이 없어져 만나게 된다면 메모리가 부족한 상태가 된다.

메모리 영역별 설명

* Program Code : 실행한 프로그램의 코드가 저장되어있다.
* Data : 전역변수와 static변수가 할당되고 프로그램 종료시까지 남아있다.
* Heap : 동적으로 할당된 메모리영역이며 프로그래머에 의해 할당(new(CPP) or malloc(C)) / 해제(delete(CPP) or free(C)) 된다.
* Stack : 지역변수와 매개변수가 할당되고 함수를 빠져나가면 자동 소멸된다.

프로그램 개발시에는 3가지 영역으로 이해하고 있으면 된다.

* Static 메모리 : 데이터 영역에 저장되고 지속성이 보장됨.
* Heap 메모리 : 힙 영역에 저장되고 지속성이 보장되나 프로그래머에의해 꼼꼼한 관리(메모리 해제)가 필요함.
* Stack 메모리 : 스택 영역에 저장되고 함수를 빠져나가면 자동 소멸됨.
※ 정적메모리 = (전역변수, static변수, 지역변수, 매개변수 저장) // 동적메모리 = (프로그램 실행중 생성되고 소멸되는 변수 저장)

동적메모리 할당

memory2

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
#include "stdafx.h"
#include <iostream>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    int* pointer = new int[100];
 
    pointer[10] = 100;   
 
    cout << "pointer Address : " << &pointer << "\n";
    cout << "new Address : " << pointer << "\n";
    cout << "value Address : " << pointer[10] << "\n";   
 
    //delete[] pointer;
    delete[] pointer;
    // 동적으로 할당한 int[100]은 해제하였더라도
    // 정적으로 할당된 pointer는 쓰레기 값을 가지게 되므로 NULL로 초기화해 안전하게 하자.
    // ※ 해제한 메모리를 또 해제할 경우 에러가 발생해 프로그램동작이 멈추게 된다.
    pointer = NULL;
    cout << "init Address : " << pointer << "\n";
 
    // pointer를 NULL로 초기화(메모리 주소값이 NULL일경우 아무일도 하지 않는다)
    // 했기 때문에 실수로 다시 해제를 하였더라도 문제가 없다.
    delete[] pointer;
 
    // new => delete, new[] => delete[] 로 쌍을 맞춰서 사용한다.
    // - 쌍을 맞추기 않을 경우 일부만 해제되는 등의 문제가 발생할 수 있다.
    int* onePointer = new int;
    *onePointer = 100;
    delete onePointer;
 
    return 0;
}
* 메모리를 동적으로 할당하고 해제한다.
* 메모리 해제 후 포인터는 NULL로 꼭 초기화해 에러를 방지한다.
* new => delete, new[] => delete[] 로 쌍을 맞춰서 사용한다.