본문 바로가기

카테고리 없음

동적할당

이거걍 정적할당은 미리 정해두고 근데 그렇다고 크기 ㅈㄴ 크게하면 최적화부터 쓸대없는 공간 낭비함

그래서 동적할당 하는건데 이거 하면 실행되면서 크기가 정해진다 그래서 유동적이다

heap영역

c언어나 자바와 같은 프로그래밍 환경에서 원시 자료형이 아닌 보다 큰 크기의 데이터를 담고자 동적으로 할당하는 메모리 공간을 자칭

c언어에서 말하는 동적할당이란 heap영역에 필요할 때마다 메모리 공간을 할당하고 더 이상 필요하지 않을 경우 메모리를 해제해주는 과정을 의미

  • 장점
    • 상황에 따라 원하는 크기 만큼의 메모리가 할당되므로 경제적 (malloc or calloc)
    • 이미 할당된 메모리라도 언제든 크기를 조정할 수 있다(realloc)
  • 단점
    • c언어의 경우 GC(Garbage Collector)가 없기 때문에 , 개발자가 직접 명시적으로 메모리를 해제해주어야 한다(free)
    • 만약 이를 하지 않았을 경우,메모리 누수가 나타나고 이는 디버깅 하기 매우 까다롭다

메모리 할당

malloc 또는 calloc을 호출하게 되면 힙 영역에 필요한 만큼의 메모리 공간을 확보하고 이후 반환타입으로 해당 메모리 공간을 확보하고 이후 반환 타입으로 해당 메모리 공간의 시작 위치를 포인터로 반환한다

또한 할당된 메모리를 어떤 목적에 사용할지 함수에서 판단하기 어렵기 때문에 ,return타입은 void* 형을 return하며 반환 받는 쪽에서 타입 캐스팅을 통해 사용해야한다

malloc 과 calloc 의 차이

각각의 선언 방법에 대한 차이는 아래와 같다

int *arr=(int *)malloc(10*sizeof(int));
int *arr=(int *)calloc(10,sizeof(int));

malloc은 매개변수로 입력한 크기만큼을 그대로 할당

calloc은 두번째 매개변수의 크기를 첫 번째 매개변수 갯수 만큼을 할당해 달라는 식으로 요청한다

위 두 명령어 모두 똑같은 크기의 공간을 확보한다

두 명령어의 차이는 초기화 값에 그 차이가 있다

malloc의 경우 메모리 공간만 할당하므로 초기화되지 않은 메모리 공간에는 쓰레기 값들이 들어있다

그러나

calloc같은 경우에는 할당후 해당 메모리 공간을 0으로 초기화한다

따라서 성능 자체는 초기화를 시키지 않는 malloc이 조금 더 낫다 그러나 상황에 따라서 초기화가 필요할 경우는 calloc을 선택하는 것도 좋은 방법이 될것같다

메모리 해제

메모리 공간은 한정적이며 더 이상 사용되지 않을 메모리 공간이라면 해당 메모리 공간을 할당 해제 해줌으로써 다른 프로그램이 해당 공간을 재활용할 수 있게 된다.

c언어에서 free함수를 이용해 특정 주소의 메모리 공간을 할당 해제 해줄 수 있다

메모리 누수란?

메모리 누수란 동적으로 할당한 메모리가 할당 해제(free) 될 수 없는 상태가 된 것을 의미한다.

결국 위와같은 상황들이 반복되면 동적으로 할당된 메모리가 해제되지 못하고 계속 남아있게 되기 떄문에, 결국 시스템의 메모리가 부족해져 운영체제가 메모리 할당에 실패하여 프로그램을 종료신다.

메모리 누수의 간단한 예시는 아래와 같다.

int *a = malloc(5); // 5byte 메모리 공간 선언
int *b = malloc(10); // 10byte 메모리 공간 선언

b = a; // b가 a의 주소를 가리킴

free(a); // a할당 해제
free(b); // b도 a의 주소를 가리키므로, a할당 해제

이 상황은 b는 결국 힙 영역에 해제되지 않고 계속 남아있게 된다

이러한 상황을 바로 메모리 누수라고 함

방지

이를 방지하기 위해서 malloc또는 calloc을 사용했다면 의식적으로 free를 사용하는 습관을 들여야 하며

동적 메모리할당을 한 포인터의 주소를 직접 바꾸는 코드는 작성하지 않는 것이 좋다

메모리 재할당

이미 할당되어 있는 메모리 공간의 크기를 변경하여 재할당 하는 것을 의미한다.

재할당은 realloc 함수를 이용해 메모리 공간 재할당이 가능하다. realloc의 함수 시그니처는 아래와 같다.

void *realloc(void *ptr, size_t size);

이를 해석해보면 ptr 위치에 해당하는 메모리 공간의 블록의 크기를 size로 조절한다는 의미가 된다.

  • ptr==null일 경우
    • 재할당을 위한 메모리 공간이 선언되어 있지 않는 것이므로, malloc 또는 calloc을 이용해 새로운 메모리 공간을 할당하는것과 동이한 기능을 수행하게 된다
  • size==0일 경우
    • 현재 ptr위치의 메모리 블록 크기를 0으로 만든다는 의미이므로 이는 곳 해당 메모리 공간을 할당 해제 한다는 의미와 같다 따라서 이는 free함수를 호출하는 것고 동일한 기능을 수행
  • ptr≠null일 경우
    • 현재 ptr위치에 할당되어있는 메모리가 있고 이 메모리 블록의 크기를size로 변경하기 위한 동작을 수행
    • 기존에 ptr 다음 블록이 이어서 위치한 상태라면 ptr이 해당 위치에서 메모리 공간의 크기를 늘리는 것은 어렵기 때문에 어쩔 수 없이 기존 ptr블록의 내용을 유지한 채로 확장된 메모리 블록을 새로운 주소에 할당받게 된다
    • 재할당은 일반적으로 기존 블록 크기볻 ㅏ크게 할당되는것이 보편적이다
    그러나 반대로 기존 블록보다 작게 할당되는 경우도 가능
  • 만약 기존에 8byte크기만큼의 블록을 4byte만큼으로 축소시키려고 한다면 재할당하는 4byte블록의 내용은 기존 8byte블록의 4byte까지의 내용으로 채워진다