C++ new(동적 메모리)

정적 메모리와 동적 메모리

정적 메모리 할당

  • 컴파일시 필요한 메모리 할당
  • 배열 : int array[32]; // 항상128byte 공간 확보
  • 사용하지 않는 메모리까지 충분히 잡아 낭비
  • 너무 큰 메모리는 할당 불가
  • 보통 수 kB까지는 스택 사용, 그 이상은 heap에 할당
  • Windows(Visual Studio)에서 기본 스택 크기는 1MB
  • Linux와 macOS에서 기본 스택의 크기는 8MB

동적 메모리 할당

  • 실행시 필요한 메모리(heap) 할당
  • 필요한 만큼만 잡음
  • 메모리의 주소를 사용(포인터 이용)하여 접근
  • malloc()/free() 사용 // C
  • new/delete사용 // C++
    • new : 메모리 할당, 할당된 메모리 시작주소 리턴됨
    • delete : 할당 받은 메모리 해제

동적 메모리를 사용하는 이유

  1. 지역 변수는 자신의 지역({ }) 내에서만 유효한데, 전역변수처럼 프로그램이 끝날 때까지 값을 유지하고 싶은 경우
  2. 프로그램 작성시(컴파일시)는 필요한 메모리 공간의 크기를 모르겠고, 프로그램을 실행할 때 메모리의 양을 결정해야 하는 경우
    • 사용자 입력에 필요한 메모리 공간을 확보하는 경우
  3. 지금까지는 프로그램을 실행하기 전에 고정된 크기를 가지도록 변수, 배열, 객체를 선언 그러나 지역 변수가 저장되는 스택은 한정되어 있어서 너무 큰 크기는 할당 어려움

단점

  • 스택보다 느림(동적 메모리 할당은 OS의 메모리 관리 시스템이 함)
  • 동적으로 확보된 기억공간은 기억공간에 이름이 없기 때문에 주소를 사용하므로 포인터에 대한이해가 필요

사용법

new 와 delete

  • new는 메모리를 동적으로 할당하고, 할당된 메모리에 대한 주소를
    반환하는 연산자이다.
    • malloc() 함수와 마찬가지로, 요구한 만큼의 메모리가 충분하지 않으면 new는
      null포인터를 반환한다.
    • int *pi=new int;
    • int *pi = (int *)malloc(sizeof(int));
  • delete는 free()함수와 마찬가지로, 더 이상 필요 없는 메모리를 해제한다.
    • delete pi;
    • free(pi);
    • 해제하지 않으면 메모리 누수(leak)가 발생하여 다른 프로그램에서도 해당 메모리는 사용하지 못한다.

장점

  • new와 delete는 malloc()과 free()에 비해 몇 가지 장점이 있다.
  • new는 지정된 형의 크기만큼 메모리를 자동적으로 할당해 준다.
  • 즉, 필요한 메모리 크기를 계산하기 위해 sizeof()와 같은 연산자가 필요 없다.
    • int *pi=new int;
    • int *pi = (int *)malloc(sizeof(int));
  • new는 지정된 형의 포인터(메모리 시작주소)를 자동적으로 반환한다.
  • new와 delete는 중첩이 가능하다.
  • 동적으로 할당된 객체를 초기화할 수 있다.
    • 생성자를 자동으로 호출한다.
  • malloc.h나 stdlib.h를 포함할 필요 없다.
#include <iostream>
class Dog{
    private:
    	int age;
    public:
    	int getAge();
    	void setAge(int a);
};
int Dog::getAge()
{
	return age;
}
void Dog::setAge(int a)
{
	age=a;
}
int main()
{
    Dog *dp;
    dp=new Dog[10]; // 객체배열 할당
        // Dog *dp=new Dog[10];
    if(!dp){
        std::cout<< "메모리할당이 되지 않았습니다.";
        return 1;
    }
    for(int i=0;i<10;i++) dp[i].setAge(i);
    for(int i=0;i<10;i++) std::cout<< i<<"번째 객체의 나이는 " << dp[i].getAge()<<" 입니다. " <<std::endl;

    delete []dp;
    return 0;
}