스터디/C(basic)

동적 할당과 메모리 관리

elenalee 2024. 4. 19. 16:55

1. 기억공간

C에서의 기억공간 

- 프로그램의 실행을 위한 기억공간은 운영체제에서 할당 

- 할당되는 기억공간의 영역 : 데이터 영역, 힙 영역, 스택 영역

 

1) 기억공간의 확보 

 

메모리 정적할당(Static Allocation)

- 기억공간의 데이터 영역과 스택 영역 이용

- 프로그램을 작성하는 단계에서 필요한 기억공간의 크기를 결정

 

메모리 동적할당(Dynamic Allocation)

- 기억 공간의 힙 영역 이용 

- 프로그램 실행중에 입력되는 자료에 맞게끔 기억공간의 크기를 결정

 

③ 기억공간의 할당영역

데이터 영역 : 전역변수와 static변수가 저장되는 영역 (정적 할당)

스택 영역 : 지역변수와 매개변수가 저장되는 영역  (정적 할당)

힙 영역 : 프로그래머의 필요에 의해 할당/소멸이 이루어지는 영역 (동적할당)

 

 

 

2) 메모리 정적할당과 동적할당 

① 메모리 정적할당 

- 변수 선언이나 배열 선언과 같이 프로그램을 작성하는 단계에서 필요한 기억 공간의 크기 결정

- 변수 선언과 같이 할당시켜줘야 할 기억공간의 크기를 명확히 알고 있을 경우, 프로그램이 시작

   될때 미리 기억 공간의 크기를 고정하여 할당 

 

메모리 정적할당의 장점과 단점 

- 변수의 기억 공간의 크기가 명확할 때 기억공간을 쉽게 사용할수 있고, 에러발생확률 저하

- 사용하게 될 기억공간의 크기를 정확히 알지 못하거나 자료 각각의 크기 차이가 심하다면, 

  자료의 크기를 크게 잡아야 하므로 기억공간의 낭비를 가져옴 

 

예) 메모리 정적할당의 문제점과 해결방법

 

3) 메모리 동적할당

 

① 메모리 동적할당의 장점과 단점 

- 힙 영역을 이용하여 프로그램 실행 중에 입력되는 자료의 크기에 맞게 기억공간을 확보

   많은 자료를 처리하는 배열의 크기를 실행 중에 정의해야 하는 경우에 특히 유용 

   (사용할만한 공간이 있어도 쪼개어져 있으면 사용불가) 

- 프로그램 실행시 기억 공간의 크기를 지정이 가능하고, 재조정도 가능

- 함수를 이용하여 동적할당 및 메모리 회수를 위한 시간과 노력 소요 

 

메모리 동적 할당순서 

ⅰ) 기억공간을 동적으로 할당받을 변수를 포인터를 이용하여 선언

ⅱ) malloc()함수 등을 이용하여 기억공간을 동적으로 할당

ⅲ) 기억공간의 사용이 끝나면 free()함수를 이용하여 기억공간을 해제

 

③ 메모리 동적할당 함수

▣ malloc() 함수

- 할당받고자 하는 바이트를 설정하여 기억공간을 동적으로 할당

- 인자로 할당받고자 하는 기억 공간의 크기를 byte단위를 전달 

   힙 영역에 그 크기만큼 기억공간 할당, 할당한 기억공간의 첫번째 주소를 반환

- void로 명시하여 어떤 형으로든 변환 가능

- 초기화 안됨 (기억공간의 초기화를 위해서는 memset() 사용, *등을 이용하여 초기화가능)

- void * malloc(size_t number_of_bytes), 예) void malloc(sizeof(int)); 

 

 calloc()함수

- 할당받고자 하는 바이트 설정, 주어진 크기를 가지는 기억 공간을 할당받음

- malloc()함수와 동일하게 힙 영역에 기억공간 할당

- 사용하는 형태와 할당된 기억공간을 0으로 초기화

- void *calloc(int n, int size); ex) void *calloc(n, sizeof(int)); 

 

realloc() 함수

- 이미 할당받은 기억 공간의 크기를 변경해야 할 필요가 있을 경우에 사용

   int *a ; 

   a = (int *) calloc(5, sizeof(int));    ➡  int형 크기의 기억공간을 5개 할당  

   a = (int *) realloc(a, 10*sizeof(int)); ➡ int형 크기의 기억 공간을 10개 재할당

                                                               기존의 기억공간의 자료를 복사해옴 

 

▣  free() 함수

- 동적으로 할당된 기억공간을 해제 (힙 영역의 할당된 공간은 프로그램 종료시까지 유지)

- 할당된 기억공간을 해제하지 않으면 기억공간의 부족 현상이 발생하므로 명시적 반납필요

- void free(void *p); 

 

2. 기억공간 관리

- 기억공간 관리를 위한 함수 - memcmp, memcpy, memset 함수

- 관련 헤더 mem.h 

 

① memcmp()함수

- 기억 공간에 들어있는 자료를 주어진 크기만큼 비교하여, 동일한지 여부를 알수 있게 해주는 함수

- 두개의 변수가 가리키는 기억 공간의 내용을 주어진 byte만큼 비교

- int memcmp(void *s1, void *s2, size_t n); 

 

② memcpy()함수

- 기억 공간에 들어있는 자료를 다른 기억공간영역으로 복사하기 위한 함수

- 원래의 기억 공간에서 주어진 바이트만큼 새로운 기억 공간에 복사

- int memcpy(void *dest, void *src, size_t n);  src에서 dest로 복사  

 

memset()함수

- 기억 공간에 들어있는 자료를 지정한 문자로 채우는 함수

- 할당된 기억 공간의 초기화나 내용 삭제를 위해 주로 사용 

- 포인터가 가리키는 곳을 주어진 값으로 지정된 byte수만큼 채움 

- void* memset(void* ptr, int value, size_t num)   예) memset(arr, 0, sizeof(int) * 5)

  ptr : 메모리의 크기를 변경할 포인터, value : 초기화 값, size : 초기화 크기 반환 값