본문 바로가기

컴퓨터/언어,프로그래밍

C언어 :: 동적 메모리 할당 - 관련 함수

1    동적 메모리 할당

이번 장에서는 프로그래밍에 자주 사용되는 라이브러리 중에 동적 메모리 할당에 관련된 부분에 대한 설명을 하고자 합니다.  프로그래밍에서 데이터를 위해 메모리를 할당하는 방법은 변수 선언에 의한 방법 외에도 필요시에 원하는 사이즈 만큼 동적으로 할당받는 방법이 있습니다.  이는 관리할 데이터의 성향과 관리 기법에 따라 선택을 하게 되는 사항인데 이들에 대해 자세히 알아보기로 합시다.

 

1.1           동적 메모리 할당 함수들

먼저 여기서는 동적 메모리 할당 함수들에 대해 먼저 살펴보기로 합시다.

 

1.1.1      malloc()

 

포맷: void *malloc(size_t size);

 

사용자가 원하는 메모리 사이즈를 입력매개변수로 전달하면 해당 함수에서 메모리를 할당하여 해당 메모리주소를 반환하는 함수입니다.  이 함수에서 할당받은 메모리는 값이 초기화가 되지 않은 상태이므로 개발자가 필요에 의해 초기화를 해 주어야 합니다.

 

#include <malloc.h>     

int max_stu;

student *p=0;

void fnInitMem()

{

    printf("관리할 최대 학생 수를 입력하세요\n");

    max_stu = fnInsertNum();

 

    p = (student *)malloc(sizeof(student)*max_stu);

    memset(p,0,sizeof(student)*max_stu);         //초기화

}

 

위의 예제 함수는 최대 학생수를 end-user가 초기에 결정을 하여 필요로 하는 만큼 메모리 공간을 할당받는 함수입니다.  student arr[MAX_STUDENT];와 같이 개발자가 최대 관리 크기를 정하고 사용할 수도 있지만 이보다 end-user가 결정을 하여 사용할 수 있다면 보다 유연한 프로그램이 될 수 있을 것입니다.

 

이와 같이 동적으로 할당받기 위해서는 해당 공간을 관리할 포인터 변수가 필요할 것입니다.  그리고, malloc등과 같이 동적 메모리 할당 함수 호출을 통해 할당받은 메모리 주소를 해당 포인터 변수에 대입을 함으로써 해당 메모리를 관리할 수 있을 것입니다.  그리고, malloc은 특정 자료형에 상관없이 메모리를 할당하는 함수라 반환값이 void *이지만 사용하는 곳에서는 해당 메모리를 구체적으로 어떠한 목적으로 사용할 것인지를 알고 있습니다.  이에 해당 목적에 맞게 강제 형변환을 사용을 하게 됩니다.  마지막으로 할당된 메모리에는 값이 초기화가 이루어지지 않은 상태이기 때문에 memset함수를 통해 할당받은 메모리 공간을 초기화하였습니다.  memset(void *p, int val, size_t size);함수는 p주소에서 size바이트만큼 val값으로 설정하는 함수입니다.

 

1.1.2      calloc()

포맷: void *calloc(size_t nelem,size_t size);

 

 calloc 함수는 size인 요소 nelem만큼의 메모리를 할당받는 함수입니다.  , malloc에서는 입력 매개변수로 할당받을 전체 사이즈를 입력매개변수로 사용하지만 calloc에서는 각 요소의 사이즈 및 개수를 입력 매개변수로 사용을 한다는 것에 차이가 있습니다.  또한, malloc에서는 메모리를 요구한 사이즈 만큼 할당만 하지 해당 메모리를 초기화 하지는 않지만 calloc의 경우는 초기화도 해 주고 있습니다. 

 

#include <malloc.h>      

int max_stu;

student *p=0;

void fnInitMem()

{

    printf("관리할 최대 학생수를 입력하세요.\n");

    max_stu = fnInsertNum();

    p = (student *)calloc(max_stu,sizeof(student));

}

 

 

1.1.3      realloc()

포맷: void *realloc(void *block,size_t size);

 

realloc함수는 기존에 할당 받은 메모리 공간의 사이즈를 변경하고자 할 때 사용하는 함수입니다.  추가된 사이즈는 초기화되지 않은 상태이지만 기존의 사이즈에는 기존 값이 유지 됩니다.  물론, realloc을 통해 기존 사이즈를 줄이는 용도로도 사용이 됩니다.

 

#include <alloc.h>      /* visual에서는 malloc.h이다. */

int max_stu;

student *p;

 

void fnInitMem()

{

    printf("관리할 최대 학생수를 입력하세요.\n");

    max_stu = fnInsertNum();

    p = (student *)malloc(max_stu*sizeof(student));

    memset(p,0,max_stu*sizeof(student));

}

 

void fnRealloc()

{

    int old_max;

    old_max = max_stu;

    printf("관리할 최대 학생수를 입력하세요.\n");

    max_stu = fnInsertNum();

    p = (student *)realloc(p, max_stu * sizeof(student));

    if(max_stu>old_max)

    {

        memset(p+old_max , 0, sizeof(student)*(max_stu-old_max));

    }

}

 

위의 fnRealloc함수를 호출하면 기존에 사용자가 입력한 학생 데이터들은 그대로 유지가 되면서 최대 학생수만큼의 사이즈로 갱신된다는 것입니다.  이를 만약 malloc함수를 사용해서 구현한다면 다음과 같은 로직이 될 것입니다.

 

void fnRealloc()

{

    int old_max;

    int *old_p;

    old_max = max_stu;

    old_p = p;

    printf("관리할 최대 학생수를 입력하세요.\n");

    max_stu = fnInsertNum();

    p = (student *)malloc(p,max_stu * sizeof(student));

    if(max_stu>old_max)

    {

        memcpy(p,old_p,sizeof(student)*old_max);

        memset(p+old_max,0,sizeof(student)*(max_stu-old_max));

    }

    else

    {

        memcpy(p,old_p,sizeof(student)*max_stu);

    }

    free(old_p);

}

 

  , realloc함수는 새로운 공간을 확보하여 기존의 값을 복사한 후에 기존의 메모리 공간을 해제하는 작업을연쇄적으로 해 주는 함수입니다.

 

1.1.4      free()

포맷: void free(void *block);

 

free()함수는 동적으로 할당한 메모리를 해제하는 함수이다.  입력 매개변수로는 동적으로 할당받은 주소를 넣어야 하며 이미 해제된 주소를 사용해서는 안됩니다.  또한, 한 번에 동적으로 할당받은 메모리는 부분적으로 해제가 불가능하며 언제나 할당받은 유닛별로 해제하게 됩니다.  그리고, 변수 선언을 통해 할당된 메모리를 free를 통해 해제 할 수가 없습니다.


제주삼다수, 2L,... 오뚜기 진라면 매운... 상하목장 유기농 흰... 남양 프렌치카페 카... 고려인삼유통 홍삼 ... 종근당건강 오메가3... 요이치 카링 유무선...