malloc과 new 개념
동적으로 메모리를 할당하기 위해서 사용하는 것이 두 가지가 있다. malloc, new
malloc은 C에서부터 사용되어온 것이고 new는 C++에서 새로 추가된 것이다.
malloc은 함수의 일종이고 new는 연산자이다.
코드는 아래와 같이 사용한다.
interger형 10개를 동적으로 할당하는 코드이다.
// malloc
int *array1 = (int*)malloc(sizeof(int)*10);
// new
int *array2 = new int[10];
둘의 차이를 보면 malloc은 형 변환(캐스팅)이 필요하고, new는 형 변환이 필요 없다.
C++에서 new 가 추가된 이유
C++에서는 단순한 자료형 외에도 '객체'라는 것이 추가되었다.
그런데 여기서 malloc함수는 메모리를 할당하는 역할만 하기 때문에, 객체의 생성을 올바르게 실행시키지 못한다.
예를 들면 아래와 같다.
Object라는 이름의 클래스를 만들었고, 클래스 생성자에서 멤버변수를 100으로 초기화 해준다.
class Object
{
private:
int m_data;
public:
Object()
{
m_data = 100;
};
Object(int data)
{
m_data = data;
};
~Object() {};
}
이러한 객체를 malloc함수를 이용하여 만들게 되면 Object의 생성자를 호출하지 않기 때문에 m_data에는 100이 아니라 0(또는 쓰레기값)이 들어있을 것이다.
new 가 하는 일
new 는 메모리를 할당하는 것(malloc의 일)외에도 하는 일들이 있다.
1. 메모리 공간의 할당
2. 생성자의 호출
3. 할당하고자 하는 자료형에 맞게 반환된 주소 값의 형 변환
하는일 1번은 malloc과 같다.
2번의 이유로 C++에서는 new를 추가하게 되었다. 객체 생성을 위해.
3번 덕분에 위의 첫 번째 예시 코드에서 캐스팅이 필요없었다. malloc은 int로 캐스팅하였음.
new 의 예외처리
보통 new는 메모리 할당이 실패할 경우 std::bad_alloc이라는 예외를 throw한다.
이렇게 예외를 던지는 new를 사용하고 싶지 않다면, nothrownew.obj를 링킹해주면 된다.
nothrownew.obj를 링킹해주면 예뢰를 던지지 않고 nullptr을 리턴한다.
사용 방법은 아래와 같이 operator new를 재정의한다.
operator new에 대한 첫 번째 인수는 size_t 이어야 하며 반환 형식은 항상 void*이다.
Class Blanks
{
Public:
Blanks(){}
void *operator new( size_t stAllocateBlock, char chInit );
};
void *Blanks::operator new( size_t stAllocateBlock, char chInit )
{
void *pvTemp = malloc( stAllocateBlock );
if( pvTemp != 0 )
Memset( pvTemp, chInit, stAllocateBlock );
return pvTemp;
}
int main()
{
Blanks *a5 = new(0xa5) Blanks;
return a5 != 0;
}
new를 사용할 때는 new 다음에 괄호()를 사용하여 크기를 지정한다.
괄호로 전달된 new의 인자는 Blank::operator new chInit에 전달된다.
메모리 할당에 실패했는지 확인은 아래와 같이 할 수 있다.
#define BIG_NUMBER 1000000000
int *pI = new int[BIG_NUMBER];
if( pI == 0x00 )
{
cout << "Insufficient memory" << endl;
return -1;
}
출처 : https://docs.microsoft.com/ko-kr/cpp/cpp/new-and-delete-operators?view=msvc-170