본문 바로가기

Study/C programming language

동적 메모리 할당

동적 메모리 할당

일반적인 C 언어에서의 변수 선언

i 정적(static)인 메모리 할당 방식
  : int a = 10;
  프로그램이 실행되기 전에 변수의 저장 공간 할당
  모듈이나 또는 프로그램이 종료되면 변수가 해지되는 방식
i
메모리 위치가 변수를 위해 확보되면
  변수의 유효 범위(life time)내에서는 그 위치가 사용되든
    그렇지 않든 변하지 않음
  : 500 개의 정수를 저장하는 배열
        사용하는 정수: 10, 490개의 기억 공간 낭비
i
메모리 사용 공간을 사전에 정확히 예측하는 것이 필요


효율적인 기억 장소 관리의 필요성

i 필요할 때 필요한 만큼 기억장소를 확보
i
불필요한 기억장소는 해제하는 것이 필요

동적인 메모리(dynamic memory allocation) 할당

i
프로그램 실행 중에 필요한 메모리를 할당
i
프로그램 실행에 더 이상 필요하지 않는 메모리는 할당한
  메모리를 해지함
i
메모리를 할당하거나 해지하기 위한 함수가 필요
  malloc( ) 함수와 free( ) 함수 사용

동적 메모리 할당 함수

동적 메모리 할당을 위한 include 파일 : stdlib.h
메모리 할당 함수 : malloc(int )

i 기능 : 요구된 바이트 수( ) 만큼 기억장소 확보
i
성공적으로 기억장소를 확보하면 기억장소의 시작 주소를
  반환하고 충분한 메모리가 없는 경우 NULL를 반환
:
  int *pt;
     
pt = malloc(200 * sizeof(int));

메모리 해제 함수 : free()

i 기능 : 미리 확보된 바이트의 블록을 해제
i
해제될 기억장소의 시작 주소를 이 함수의 인자로 사용
:
    free (pt);

함수 malloc()

동적 메모리 할당 함수의 사용 예제

  int *pi;
  pi = (int *) malloc( sizeof(int) );
  *pi = 3;
i
정수형(int)의 메모리 공간을 동적으로 할당
i
확보된 공간의 주소는 int *의 변수에 저장
i
간접연산자 *pi를 이용하여 원하는 값을 저장
i
메모리에 4바이트가 할당된 모습
   
    pi       ->         3
            int 4 바이트의 저장공간

메모리 해제

할당된 메모리의 동적 해제

i 함수 malloc()에 의하여 동적으로 할당된 메모리 공간이
  더 이상 필요가 없거나,
  프로그램을 종료하는 경우에 반드시 메모리를 해제
i
변수 pi에 할당된 메모리의 해제
          free(pi);
i
성공적으로 메모리가 해제되면
  변수 pi NULL 값을 가짐
  더 이상 4바이트의 공간은 사용 불가능
    pi
    NULL           3

동적 메모리 할당 함수의 사용 예제

배열의 크기를 입력 받아 기억 장소 할당하기 위한 코드


int numgrades;
int *grades;
              /* 정수형 포인터 변수 정의 */
   
printf("Enter the number of grades : ");
scanf("%d", &numgrades);

/* 요구된 만큼의 정수형 배열을 위한 기억장소 할당 */
grades = (int *) malloc(numgrades * sizeof(int));


예제

#include <stdio.h>
#include <stdlib.h>
void main(void)
{
    int numgrades;
    int *grades;
    printf("Enter the number of grades : ");
    scanf("%d", &numgrades);
    grades = (int *) malloc(numgrades * sizeof(int));
    if (grades == (int *) NULL) {     /* 메모리 할당이 정상인지 검사 */
        printf("Failed to allocate grades array ");
        exit(1);
    }
    for (i=0; i < numgrades; i++)
        scanf("%d", &grades[i]);
    printf("\n An array was created for %d integers", numgrades);
    printf("\n The vales stored in the array are:");
    for (i=0; i < numgrades; i++)
        printf(" %d", grades[i]);
  free(grades);
 }


함수 calloc()

메모리 공간을 확보하면서 초기 값을 0으로 저장하는 함수

i 함수 malloc()은 메모리 공간을 확보하고 초기 값을 저장하지 않음
i
함수 calloc()은 함수 원형이 stdlib.h 헤더 파일에 정의
i
함수의사용 예

    int *ary;
    ary = (int *) calloc( 3, sizeof(int) );

    첫 번째 인자 : 할당될 메모리 항목의 갯수
    두 번째 인자 : 할당될 한 원소의 메모리 크기

i
함수 calloc()을 위와 같이 사용하면 변수 ary int형 원소 3개를 확
  보한 저장공간을 기본 값 0으로 저장

함수 realloc() : 이미 확보한 저장공간을 새로운 크기로 변경

i
함수 realloc()은 성공적으로 메모리를 할당하면 변경된 저장공간의
  시작 주소를 반환하고, 실패하면 NULL을 반환
i
함수 사용 예제

    int *reary, *cary;
   
cary = (int *) calloc( 3, sizeof(int) );
             
:
    reary = (int *) realloc( cary, 4*sizeof(int) );


    첫 번째 인자 : 변경할 저장공간의 주소
    두 번째 인자 : 변경하고 싶은 저장공간의 크기

i
함수 realloc()에서 첫 번째 인자가 Null 인 경우
    함수 malloc()과 같은 기능 : 지정된 크기만큼의 새로운
    공간을 할당

함수 realloc() 이해

realloc( ) 함수에 대한 메모리 할당

i 변수 cary에 대한 realloc() 함수 적용
  reallco( ) 함수의 메모리 할당 방법
      : 기존 영역을 사용하여 확장하는 방법
      : 새로운 영역에서 다시 할당을 받는 방법 (이전 값의 복사)
i
함수 realloc()에 의하여 확장되는 공간

  malloc()과 같이 기본 값이 저장되지 않음

메모리 관련 함수 (요약)

메모리 할당과 해제에 관련된 함수들

             

  메모리                   사용 함수                         기능

 메모리 할당               malloc(size_t)           인자만큼의 메모리 할당 후
 (기본값 없이)                                       기본 주소 반환
                           
 메모리 할당           calloc(size_t , size_t)   
뒤 인자만큼의 메모리 크기
(
기본값 0으로)
                                      로 앞 인자 수 만큼 할당 후
                                                      기본 주소 반환
                                 
기존 메모리 변경       realloc(void *, size_t)    
앞 인자의 메모리를 뒤 인
 (이전값 그대로)                                    자 크기로 변경 후, 기본 주                                                     소 반환
                                 
  메모리 해제              free(void *)          
인자를 기본 주소로 갖는
                                                      메모리 해제


메모리 할당 함수 사용 예제 (1)

함수 realloc()의 기능

i
함수 calloc()으로 정수형 저장 공간 2개를 할당하는 문장

cary = (int *) calloc( 2, sizeof(int) );
if (cary == NULL) {
          printf("메모리 할당이 문제가 있습니다.\n");
          exit(1);
}
printf("cary
주소는 %#X이다. \n", cary);

i 배열 cary의 원소 값을 출력하고, 다시 10, 11을 저장

for (i = 0; i < 2; i++)
   
printf("cary[%d](%#X) = %d ", i, cary + i, *(cary + i));
printf("\n\n");
cary[0] = 10; cary[1] = 11;


메모리 할당 함수 사용 예제 (2)

i 메모리 포인터 cary를 이용하여 다시 크기가 6인 배열을 할당
  cary 배열은 원소 수가 2이고, 새로 할당한 reary 배열은
    원소 수가 6인 배열

reary = (int *) realloc( cary, 6*sizeof(int) );
if (reary == NULL) {
      printf("
메모리 할당에 문제가 있습니다.\n");
      exit(1);
}
printf("realloc()
호출 후에 cary 주소는 %#X이다. \n", cary);
printf("realloc()
호출 후에 reary 주소는 %#X이다. \n", reary);

i 배열 reary reary[0] reary[1] cary[0] cary[1]의 값
  과 같고, 배열 reary의 나머지 값은 아직 미정

메모리 할당 함수 사용 예제 (3)

i 미정인 나머지 값을 다음과 같이 저장

reary[2] = 30;               //reary[3]에는 저장을 하지 않음
reary[4] = 40; reary[5] = 50;


i
배열 reary를 출력하면 어떤 값이 나올 지 예상

for (i = 0; i < 6; i++) {
     
printf("reary[%d](%#X) = %d ", i, reary + i, *(reary + i));
}
printf("\n");


구조체 동적 기억장소 할당

struct office {
   
int x;
   
char y;
   
char z[10];
 };

 

struct office *offi;       /*할당된 주소를 저장하기 위한 포인터 변수 */
/*
구조체를 저장하기 위한 공간 확보 */
offi = (struct office *) malloc( sizeof(struct office));
/*
공간이 할당되었는지를 점검 */
if (office == (struct office *) NULL) {
    printf("\n Allocation of office record failed");
    exit(1)
}