c언어 동적할당

minm·2025년 5월 3일

정보처리기사

목록 보기
6/8

정처기에 동적할당 나와서 급하게 정리해봄. 2회차 다시 쳐야 할 거 같음.

메모리 동적할당

변수나 배열은 컴파일 타임에 크기가 결정되는데 동적 메모리 할당은 런타임 중에 메모리의 크기를 결정하고 할당하는 방식을 말한다.

c언어에서는 malloc 함수를 사용하여 메모리를 동적으로 할당할 수 있다.

힙 영역

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

동적할당

malloc을 호출하게 되면 힙 영역에 필요한 만큼의 메모리 공간을 확보하고 이후 반환 타입으로 해당 메모리 공간의 시작 위치를 포인터로 반환하며 할당된 메모리를 어떤 목적에 사용할지 함수에서 판단하기 어렵기 때문에, return 타입은 void * 형을 return 하며, 반환 받는 쪽에서 타입 캐스팅을 통해 사용해야한다.

#include <stdlib.h>

void * malloc(size_t size);
출처: https://ttl-blog.tistory.com/1068 [Shin._.Mallang:티스토리]

동적할당의 문제점 -> 메모리 누수

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

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

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

위 코드의 경우 b는 결국 힙 영역에 해제되지 않고 계속 남아있게 된다. 이런 상황을 메모리 누수라고 한다. 따라서 의식적으로 free를 사용하는 습관을 들여야 함!

메모리할당 코드 예제

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

int main(void) {
    int arr[4] = { 4, 3, 2, 1 };    // 크기가 4인 배열 선언
    int* pArr;                      // int 타입을 가리키는 포인터 pArr 선언

    // int 타입 사이즈 * 4 만큼의 메모리를 동적으로 할당
    pArr = (int *)malloc(sizeof(int) * 4);

    if (pArr == NULL) {
        // 메모리 할당에 실패한 경우
        printf("malloc error\n");
        return 1;
    }

    // 배열 복사
    for (int i = 0; i < 4; ++i) {
        pArr[i] = arr[i];
    }

    // 출력
    for (int i = 0; i < 4; ++i) {
        printf("%d\n", pArr[i]);
    }

    // 할당한 메모리 해제
    free(pArr);

    system("pause");  // 윈도우 환경에서 프로그램 종료 전 일시 정지
    return 0;
}

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

int main(void) {
    int num;
    int *pArr;
    int average = 0;

    printf("몇 개의 과목을 저장할 것인가 자네 : ");
    scanf("%d", &num);

    // 0개 넣으면 프로그램 종료
    if (num == 0) {
        return 0;
    }

    // 과목 개수만큼 메모리 동적할당
    pArr = (int*)malloc(sizeof(int) * num);

    // 동적할당 실패
    if (pArr == NULL) {
        printf("malloc error\n");
        exit(1);
    }

    // 점수 입력 및 저장
    for (int i = 0; i < num; ++i) {
        printf("[%d/%d] 점수 입력 : ", i + 1, num);
        scanf("%d", &pArr[i]);
    }

    // 점수 출력
    for (int i = 0; i < num; ++i) {
        printf("%d번째 과목의 점수 : %d\n", i + 1, pArr[i]);
    }

    // 평균 계산
    for (int i = 0; i < num; ++i) {
        average += pArr[i];
    }

    // 정수 나눗셈으로 소수점 이하 버림
    average /= num;
    printf("평균 : %d\n", average);

    // 동적할당 해제
    free(pArr);

    system("pause");  // 윈도우 환경에서 종료 전 대기
    return 0;
}

0개의 댓글