Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

heenam

Chapter 25 메모리 관리와 메모리의 동적 할당 본문

[Programming Language]/C

Chapter 25 메모리 관리와 메모리의 동적 할당

znzltiq 2020. 4. 23. 17:09

C언어의 메모리 구조

 메모리의 구성

   프로그램 실행 시 운영체제에 의해서 마련되는 메모리의 구조는 다음과 같이 네 개의 영역으로 구분이 된다.

코드 영역
데이터 영역
힙 영역
스택 영역

  메모리 공간을 나눠놓은 이유는 유사한 성향의 데이터를 묶어서 저장을 하면, 관리가 용이해지고 메모리의 접근

  속도가 향상된다.

 메모리 영역별로 저장되는 데이터 유형

  + 코드영역

   코드 영역은 이름 그대로 실행할 프로그램이 코드가 저장되는 메모리 공간이다.

   따라서 CPU는 코드 영역에 저장된 명령문들을 하나씩 가져가서 실행을 한다.

  + 데이터 영역

    데이터 영역에는 전역변수와 static으로 선역되는 static변수가 할당된다. 즉, 이 영역에 할당되는 변수들은

    프로그램의 시작과 동시에 메모리 공간에 할당되어 프로그램 종료 시까지 남아있게 된다는 특징이 있다.

  + 스택 영역

    스택 영역에는 지역변수와 매개변수가 할당된다. 이렇듯 이 영역에 할당되는 변수들은 선언된 함수를 빠져나가면

    소멸된다는 특징이 있다.

  + 힙 영역

    C언어에서는 프로그래머가 원하는 시점에 변수를 할당하고 또 소멸하도록 지원을 하는데, 바로 이러한 유형의

    변수들이 할당되는 영역이 힙 영역이다.

메모리의 동적 할당

  지역변수와 같이 함수가 호출될 때마다 매번 할당이 이뤄지지만, 할당이 되면 전역변수와 마찬가지로 함수를

  빠져나가도 소멸되지 않는 성격의 변수가 필요하다. 그런데 다행스럽게도 이렇듯 생성과 소멸의 시기가 지역변수나

  전역변수와 다른 수영의 변수malloc과 free라는 이름의 함수를 통해서 힙 영역에 할당하고 소멸할 수 있다.

 힙 영역의 메모리 공간 할당과 해체: malloc과 free함수

  힙 영역을 흔히 '프로그래머가 관리하는 메모리 공간'이라고 한다. 이유는 malloc함수호출로 할당된 메모리 공간은

  프로그래머가 직접 free 함수의 호출을 통해서 해제하지 않으면 계속 남아있기 때문이다.

  즉, 두 함수는 다음과 같이 쌍을 이루어 호출하게 된다.

#include <stdio.h>

int main()
{
	void * ptr1 = malloc(4); // 4바이트가 힙 영역에 할당
    void * ptr2 = malloc(12); // 12바이트가 힙 영역에 할당
    
    ....
    free(ptr1); // ptr1이 가리키는 4바이트 메모리 공간 해제
    free(ptr2); // ptr2이 가리키는 12바이트 메모리 공간 해제
    ....
}

  이렇듯 malloc함수는 인자로 전달된 정수 값에 해당하는 바이트 크기의 메모리 공간을 힙 영역에 할당하고, 이 메모리

  공간의 주소 값을 반환한다. 이어서 free함수를 호출하는 시점에 가리키는 메모리 공간이 소멸된다. 무엇보다도 malloc

  함수는 free함수는 호출 위치 및 시점에는 제한이 없어 원하는 시점에 할당하고 소명 가능하다.

 malloc 함수의 반환형이 void형 포인터인 이유와 힙 영역으로의 접근

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int * ptr1 = (int *)malloc(sizeof(int));
    int * ptr2 = (int *)malloc(sizeof(int)*7);

    *ptr1 = 20;
    for (int i = 0; i < 7; i++)
        ptr2[i] = i+1;

    printf("%d\n", *ptr1);
    for (int i = 0; i < 7; i++)
        printf("%d", ptr2[i]);

    free(ptr1);
    free(ptr2);

}
//******참고******
//메모리 할당의 성공여부를 확인하고자 한다면
	int * ptr = (int *)malloc(sizeof(int));
	if (ptr == NULL)
    {
    	//메모리 할당 실패에 따른 오류의 처리
    }

 malloc함수의 사촌 뻘 되는 calloc 함수

  malloc 와 calloc의 차이점은 malloc 함수와는 달리 두개의 숫자를 인자로 전달 받는다.

  예를 들면 void * ptr1 = calloc(30,4) 이런식으로 호출한다면 "4바이트 크기의 블록(elt_size) 30개를 (elt_count)

  힙영역에 할당해 주세요." 라는 뜻이된다. 또 다른 차이점은 calloc하수는 할당된 메모리 공간의 모든 비트를 0으로

  초기화 시키기 때문에 malloc처럼 쓰레기 값으로 채워지지 않는다.

 힙에 할당된 메모리 공간 확장 시 호출하는 realloc 함수

  한번 할당된 메모리 공간은 그 크기를 확장할 수 없다. 하지만 그 영역이 힙이라면, 그리고 realloc함수를 사용한다면

  가능해 진다.

#include <stdio.h>

int main(void)
{
	int * arr = (int *)malloc(sizeof(int)*3); // 길이가 3인 int형 배열 할당
	.....
	arr = (int *)realloc(arr, sizeof(int)*5); // 길이가 5인 int형 배열로 확장
	.....
}