티스토리 뷰

2021.03.04.목

malloc, free 함수

✔  malloc() 함수를 사용해서 동적 메모리를 할당받고, free() 함수를 사용해서 반환한다.

✔  malloc() 함수와 free() 함수는 <stdlib.h> 헤더 파일에 포함되어 있으니 전처리가 필요하다.

(포인터 형변환) malloc (메모리크기);
int * p = (int *) malloc (sizeof(int));

✔  malloc() 함수는 void 포인터를 반환하므로, 포인터 변수에 저장할 때에는 필요한 자료형으로 형변환해야한다.

✔  필요한 만큼 공간을 할당받을 수 있는데, 이는 byte기준이며, sizeof() 연산자를 사용해 크기를 계산해 넣어주자.

✔  그렇게 하면 컴파일러나 운영체제에 따라 int형 변수의 크기가 다르더라도 수정할 필요가 없다.

int *p = (int*)malloc(sizeof(int)*10);	
if(p==NULL
	printf("동적 메모리 할당 실패\n");
	return 1;
}

✔  메모리 공간이 부족하여 동적 메모리를 할당하지 못하면, malloc() 함수는 0(null)을 반환한다.

✔  if문을 사용해 위와 같이 반환 값을 검사하여 메모리 공간이 부족한 상황을 대비하자.

int * p = (int *) malloc (sizeof(int));
free(p);

✔  malloc() 함수를 사용해 할당받은 메모리 공간은 사용이 끝나면 반드시 반환해야 한다.

✔  지역 변수에게 할당된 메모리 공간은 함수가 종료될 때 자동 반환되지만 동적 메모리 공간은 그대로 남아있다.

✔  따라서 함수가 반환되기 전에, 동작 할당받은 공간은 free() 함수로 직접 반환해야 한다.

 

 

동적 할당 영역을 배열처럼 쓰기
int * pa = (int *) malloc (sizeof(int)*10);

✔  형태가 같은 변수가 많이 필요하다면, 한 번에 많은 저장 공간을 할당하여 배열처럼 사용할 수 있다.

✔  위와 같이 int형 변수 10개를 저장할 수 있는 동적 메모리를 할당받아

✔  포인터 변수 pa에 저장하면 배열처럼 사용할 수 있다.

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

int main(void){
  int sum = 0;
  int *pa = (int*)malloc(sizeof(int)*5);
  for(int i=0; i<5; i++){
    scanf("%d", pa+i);
    sum+=pa[i];
  }
  printf("합은 %d",sum);
  free(pa);
  return 0;
}

 

 

기타 동적 할당 함수

✔  동적 메모리를 할당받을 때 가장 많이 사용하는 함수는 malloc()이지만, 다른 함수도 존재한다.

// calloc 함수 원형
void *calloc(unsigned int, unsigned int);

// calloc 함수 사용 예제
int * p;
p = (int*)malloc(sizeof(int)*10);
p = (int*)calloc(10, sizeof(int));

✔  calloc() 함수는 동적 메모리 공간을 할당 받음과 동시에 0으로 초기화한다.

✔  malloc() 함수는 int형 변수 10개를 저장할 수 있는 동적 메모리를 할당받을 때 sizof(int)*10이라고 입력하는데

✔  calloc() 함수는 첫 번째 인수로 필요한 공간의 개수 10을 전달하고, int형의 크기를 두 번째 인수로 전달한다.

// realloc 함수 원형
void *realloc(void *, unsigned int);

// realloc 함수 사용 예제
int * p;
p = (int*)malloc(sizeof(int)*10);
p = (int*)realloc(p, sizeof(int)*20);

✔  realloc() 함수는 이미 할당받은 메모리 공간의 크기를 조절한다. 

✔  malloc() 함수를 사용해 int형 크기의 10개 공간을 처음에 할당받았는데

✔  realloc() 함수를 사용해 int형 크기의 20개 공간으로 다시 메모리 공간의 크기를 조절했다.

✔  메모리 공간 크기를 늘리는 경우는 상관없지만, 줄이는 경우에는 데이터 소실이 있을 수 있으니 주의하자.

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

int main(void){
  int size = 5;
  int * pi = (int*)calloc(size, sizeof(int));
  int cnt = 0;
  int num;

  printf("> 입력을 멈추고 싶다면 -1을 입력하세요\n");
  while(1){
    scanf("%d", &num);	
    if(num==-1) break; 	
    //반복 횟수를 통해 남은 저장 공간을 확인하고
    //남은 저장 공간이 없으면 size를 +5해주고 동적 메모리 공간 재 할당.
    if(cnt==size){		
      size+=5;
      pi = (int*)realloc(pi, sizeof(int)*size);
    }
    pi[cnt]=num;
    cnt++;
  }
  for(int i=0; i<size; i++){
    printf("%5d", pi[i]);
    if((i+1)%5==0) printf("\n");
  }
  
  free(pi);
  return 0;
}	

✔  realloc() 함수는 인자를 통해서 크기를 변경할 포인터를 받는데, 왜 다시 대입해줘야 할까?

✔  크기를 늘리는 경우, 연속적인 메모리공간 할당이 불가능할 때 해당 동적 메모리는 해제하고

✔  새로운 주소의 동적 메모리를 할당한다. 그래서 다시 포인터변수에 주소를 대입해주어야만 한다.

 

 

 

 

 

[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩 도장 / 위키백과

댓글
«   2025/04   »
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
최근에 올라온 글
글 보관함
Total
Today
Yesterday