리메이크 중/C,C++ 이론 중심

C(&C++) 이론 20. 동적 할당

라이피 (Lypi) 2023. 2. 13. 18:38
반응형

 


내용 참고

C++ 기초플러스 4판 (성안당)

혼자 연구하는 C/C++ (Soen.kr/와우북스)


동적 할당

■  동적 할당이란 프로그래밍 시점에서는 메모리가 얼마나 필요한지 알 수 없어 실행 중에 메모리를 할당하는 것을 말한다.

■  예를 들어 주소록을 저장하는 배열을 만들어야 하는데, 몇명이나 저장해야 할지 모를 때 동적할당을 사용한다.

■  동적할당 대신에 충분히 큰 배열을 만들어 놓으면 대처할 수는 있겠지만 이 경우에는 메모리 낭비가 극심할 것이다.


 

■  C언어에서는 동적할당을 위해서 malloc()과 free()라는 함수를 사용했다.

■  C++에서는 언어에서 지원하는 new와 delete라는 전용 연산자를 사용한다.

■  C++의 명령어가 더 사용이 편하고 직관적이기 때문에 주로 C++의 방법이 사용된다.

■  여기서 free()와 delete는 할당받은 메모리를 반납하는 역할을 한다.

ⅰ. C언어의 경우

■  C언어에서 임의의 크기를 갖는 int형 배열을 동적할당하고 싶다면 아래와 같이 쓰면 된다.

int* pi;
int num;

pi = (int*)malloc(num * sizeof(int));

free(pi);

■  일반 배열이면 변수인 num으로 크기 지정을 할 수 없기 때문에 동적할당을 해야한다.

■  malloc() 함수는 void형 포인터를 반환하므로 필요한 타입으로 캐스팅이 필요하다.

■  malloc() 함수의 인자로는 동적할당 받을 크기를 넣어줘야 하므로 갯수 * 타입의 크기를 계산해서 넣는다.

■  마지막에 동적할당받은 메모리를 free() 함수로 반환한다.

■  free() 함수의 인자로 동적할당 받은 포인터를 넘기면 된다.

 

■  위의 예제의 전체 코드는 아래와 같다.

#include <iostream>
using namespace std;

int main()
{
    int* pi;

    int num;
    cin >> num;

    pi = (int*)malloc(num * sizeof(int));

    for (int i = 1; i <= num; i++) {
        pi[i-1] = i;
        cout << pi[i-1] << endl;
    }

    free(pi);

    return 0;
}

■  num 변수에 임의의 수를 입력받아 int형 포인터인 pi에 그만큼의 사이즈를 동적할당 받았다.

■  동적할당된 배열에는 간단하게 차례대로 1부터 num까지의 숫자를 저장한뒤 출력했다.

 

ⅱ. C++의 경우

■  C++에서 임의의 크기를 갖는 int형 배열을 동적할당하고 싶다면 아래와 같이 쓰면 된다.

int* pi;
int num;

pi = new int[num];

delete[] pi;

■  new 연산자의 뒤에 어떤 타입을 몇개 받을지 적어주면 끝이다.

■  뒤에 타입을 적기 때문에 따로 캐스팅할 필요가 없으며, 크기 계산도 필요 없어졌다.

■  주의할 점은 new int; 로 int형 한개를 동적할당 받는 경우에는 delete pi;로 반환하지만,

■  위와 같이 new int[num];으로 임의의 갯수를 배열로 할당받는 경우에는 delete[] pi;로 반환해야 한다는 것이다.

■  new와 delete, new (타입)[]와 delete[]의 두쌍이 있다고 생각하는게 좋다.

■  delete를 빠트리거나 잘못 쓸 경우 컴파일 에러가 나지 않고, 메모리가 누수되므로 작성 시점에서 주의해야한다.

#include <iostream>
using namespace std;

int main()
{
    int* pi;

    int num;
    cin >> num;

    pi = new int[num];

    if (pi != NULL) {
        for (int i = 1; i <= num; i++) {
            pi[i-1] = i;
            cout << pi[i-1] << endl;
        }
    }

    delete[] pi;

    return 0;
}

 

■  할당에 실패할 경우 null포인터를 반환하므로 위에서는 if문으로 예외처리를 해주었다.

 

 


반응형