본문 바로가기
프로그래밍 언어/C 언어

[C] 동적 할당 필요성

by 까망 하르방 2021. 3. 20.
반응형

동적 할당 필요성

동적 할당은 할당되는 메모리의 크기를 컴파일러가 결정하지 않고

프로그램 실행 중간에 호출되는 malloc 함수가 결정

※ 메모리를 동적으로 할당하는 키워드로는 malloc, calloc 등이 존재합니다.

 

malloc 함수 사용 형태

인자로 전달된 정수 값에 해당하는 바이트 크기의 메모리 공간을 힙 영역에 할당하고

이 메모리 공간의 주소 값을 반환 (실패할 경우 NULL 반환)

int *ptr = (int *)malloc(sizeof(int));

double *ptr = (double *)malloc(sizeof(double));

동적 할당 과정

 

 

일반 변수에서 값에 의한 복사를 이용하는 경우에는 큰 문제는 없습니다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

char* readName(void) {
    int result;
    printf("number: ");
    scanf("%d", &result);
    return result;
}

int main(void) {
    int a, b;
    a = readName();
    printf("%d \n", a);

    b = readName();
    printf("%d \n", b);

    printf("\n");
    printf("%d \n", a);
    printf("%d \n", b);
}

코드 결과

 

 

하지만 문자열이나 배열과 같은 참조에 의한 복사할 때는 아래와 같은 문제가 발생합니다.

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

char* readName(void) {
    char name[30];
    printf("name: ");
    gets(name);
    return name;
}

int main(void) {
    char* name1, * name2;

    name1 = readName();
    printf("%s \n", name1);

    name2 = readName();
    printf("%s \n", name2);
}

 

 

* 지역 변수는 함수 반환 후에 유지 되지 않습니다. 

readName()에서 name 변수의 주소 값을 반환하는데, 함수가 종료되면서 메모리가 소멸되어

실제값에서는 예상치 못한 결과를 받게 됩니다. 

코드 결과

 

이러한 문제를 해결하고자 전연변수로 전환 시도.

전역 변수: 하나의 전역변수가 다른 값으로 덮어씌워져 잘못 사용됨.

#include <stdio.h>

char name[30];

char* readName(void) {    
    gets(name);
    return name;
}
int main(void) {
    char* name1, * name2;
    name1 = readName();
    printf("%s \n", name1);
    name2 = readName();
    printf("%s \n", name2);

    printf("\n");
    printf("%s \n", name1);
    printf("%s \n", name2);
}

각각의 이름정보를 유지하지 못합니다.

코드 결과

 

결과적으로 함수가 매번 호출될 때마다 새롭게 할당되고 또 함수를 빠져나가도 유지가 되는 유형의 변수가 필요

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

char* readName(void) {    
    char* name = (char*)malloc(sizeof(char) * 30);
    printf("name: ");
    gets(name);
    return name;
}

int main(void) {
    char* name1, * name2;
    name1 = readName();
    printf("%s \n", name1);

    name2 = readName();
    printf("%s \n", name2);
    printf("\n");

    printf("%s \n", name1);
    printf("%s \n", name2);

    free(name1); free(name2);
}

메모리 공간의 주소를 반환받기 때문에 포인터 변수를 이용해 접근할 수 밖에 없는 형태.

코드 결과

 

free() 함수

호출하는 시점에 해당 메모리 공간이 소멸

Q. free 함수를 호출하지 않으면 프로그램 종료 후에도 메모리가 남게 되나요?

A. 아니요! 프로그램 실행 시 할당된 모든 메모리 공간은 프로그램이 종료되면

     운영체제에 의해서 전부 해제가 되기 때문이다.

 

※ C 언어에서 스택에 선언된 변수는 따로 메모리 해제를 해주지 않아도 되지만,

    반면에 동적 할당된 변수는 free() 함수로 메모리 해제를 해주어야 합니다.

    실습 수준의 간단한 프로그램은 큰 문제가 없지만 실무에서 메모리 상의 프로세스 무게가 더해져

    오류가 발생할 수 있기 때문입니다. 메모리 누수(Memory Leak)를 습관적으로 방지하여야 합니다.

반응형

'프로그래밍 언어 > C 언어' 카테고리의 다른 글

[C] Call-by-value & Call-by-reference  (0) 2021.03.20
[C] 포인터와 배열의 관계  (0) 2021.03.20
[C] [전처리기] #ifdef  (0) 2021.03.20
[C] calloc( ) & realloc( )  (0) 2021.03.20
[C] 문자열  (0) 2021.03.20

댓글