정체불명의 모모
[ C / C++ ] malloc( ) 와 new 의 차이점 본문
최근 면접에서 대답 하지 못했던 부분에 대해 공부를 해보았습니다.
평소에 크게 신경쓰지 못했던것 이었는데,
더 근본적인 부분들을 신경써보게 되는 계기가 되었다.
질문 : malloc 과 new의 차이점이 무엇인가요?
Vector 자료구조를 C++ 구현해 보면서 malloc( ) 과 new의 차이점에 대해서 파악해 보았습니다.
Vector는 Template로 구현했습니다.
우선 전체 코드
malloc() 과 new를 나눠서 컴파일 결과를 확인하기 위해
MALLOC 매크로와 전처리기를 통해 나누어 주었습니다.
#pragma once
#include <iostream>
#define MALLOC // malloc Test Define
template <typename T>
class MyVector
{
public:
MyVector()
{
#ifdef MALLOC
Arr = (T*)malloc(sizeof(T) * BasicAllocateSize);
#else
Arr = new T[BasicAllocateSize];
#endif
Size = 0;
AllocatedSize = BasicAllocateSize;
}
~MyVector()
{
#ifdef MALLOC
free(Arr);
#else
delete[] Arr;
#endif
}
void PushBack(const T& value)
{
TryNewAllocate();
Arr[Size] = value;
Size++;
}
template<typename ...Args>
void Emplace_Back(Args&&... args)
{
TryNewAllocate();
new(&Arr[Size]) T(std::forward<Args>(args)...);
Size++;
}
private:
void TryNewAllocate()
{
if (AllocatedSize <= Size)
{
NewAlloc();
}
}
void NewAlloc(int DesiredSize = 0)
{
if (DesiredSize == 0)
{
AllocatedSize = AllocatedSize * 2;
}
else
{
if (AllocatedSize >= DesiredSize)
return;
AllocatedSize = DesiredSize;
}
#ifdef MALLOC
T* NewArr = (T*)malloc(sizeof(T) * AllocatedSize);
#else
T* NewArr = new T[AllocatedSize];
#endif // MALLOC
for (int i = 0; i < Size; ++i)
{
NewArr[i] = Arr[i];
}
#ifdef MALLOC
free(Arr);
#else
delete[] Arr;
#endif
Arr = NewArr;
}
private:
T* Arr;
int Size;
int AllocatedSize;
static const int BasicAllocateSize = 10;
};
class Point
{
public:
Point()
{
std::cout << " Point::기본 생성자! " << std::endl;
}
Point(int _x)
:X(_x), Y(0)
{
std::cout << "Point::int 형 생성자! " << std::endl;
}
Point(int _x, int _y)
:X(_x) , Y(_y)
{
std::cout << " Point:: int, int 형 생성자! " << std::endl;
}
void operator=(Point other)
{
X = other.X;
Y = other.Y;
std::cout << "Point::대입연산자!" << std::endl;
}
private:
int X;
int Y;
};
#include "TemplateVectorAgain.h"
// 실행 코드
int main()
{
MyVector<Point> v;
v.Emplace_Back();
v.Emplace_Back(1, 3);
v.Emplace_Back(1);
}
▷ malloc( )으로 메모리 할당을 할 경우
: malloc은 자료형의 크기를 매개 변수로 넣어줘 메모리 할당을 해 줍니다.
template <typename T>
T* Arr = (T*)malloc(sizeof(T)*arrSize); //arrSize = 10;
▷ malloc( ) 로 컴파일 했을 경우
▷ new키워드로 메모리 할당을 할 경우
: new 키워드를 붙여서 메모리를 할당해 준다.(매우매우 간단스)
template <typename T>
T* Arr = new T[arrSize]; //arrSize = 10;
▷ new키워드로 컴파일 했을 경우 ( 그저 위의 코드에서 #define 부분만 주석 처리 해주면 된다.)
위의 컴파일 결과를 보면 확실히 다르다는 것을 느낄 수 있다.
◇ 차이점
ㆍ malloc( ) 는 자료형 크기만큼 메모리만을 할당을 하고 생성자를 불러오고 있지 않다.
ㆍ new 키워드는 자료형 크기 만큼 메모리 할당을 해주고, 배열의 수 만큼 객체를 채워 넣어 생성자를 불러주고 있다.
그렇기에 메모리 할당하는 부분에 있어서 10번의 생성자가 호출된 것 이다.
(할당과 동시에 초기화 가능)
◇ 그럼 C++에서는 왜 new 와 delete 란 연산자를 이용해 메모리를 할당 해제 해주는 걸까?(인터넷 리서칭)
: C언어에서 사용한 malloc는 함수이기 때문에 C언어의 문법에 포함되지 않습니다.
그냥 C언어 문법(컴파일러가)이 만들어진 이후에 추가적으로 만들어진 함수일 뿐입니다.
그래서 malloc 함수와 컴파일러는 서로간의 문법적으로 약속된 부분이 없어서 매개변수나 형 변환 그리고 sizeof 연산자를
사용해서 표현을 할 수밖에 없습니다.
하지만, new 연산자는 연산자이기 때문에 컴파일러와 문법 형식을 약속하였습니다.
그래서 컴파일러와 약속된 문법을 사용하면 정해진 방식으로 처리해 주기 때문에 malloc 함수보다 좀더 단순한 표현이 가능합니다.
(가독성이 좋고 편리함)
◇ 그럼 malloc( ) 와 new 연산자 어느것이 더 빠를까?
: 그것은 나로써는 정확히 모르겠지만, new 연산자 안에 결국 malloc 함수를 호출한다고 알고 있다.
그렇기에 malloc( )가 더 빠르다는 말이 많다.(정확한것은 실험을 한번 해봐야 겠다.)
코드의 사용법에 맞춰 둘중 하나를 선택해 사용하면 훨씬 효율적인 코드가 될 것 같다.
매우 흥미로운 공부였던것 같다.
점점 가깝고도 멀게 느껴지는 C++...
좀 더 친해지고 싶다. ㅡㅜ
(혹시... 깃허브에 코드를 올려 놓았으니.. 보실분들은..)
'프로그래밍(c++)' 카테고리의 다른 글
[C++] std::allocator<T> 클래스 (0) | 2021.08.05 |
---|---|
[스마트 포인터] Shared_ptr 알아보기(구현) (0) | 2021.07.15 |
[c++ ] c++로 List 구현 (0) | 2020.09.06 |
c++ 04 : 클래스는 객체의 설계도 [ 클래스와 객체 / 어서와c++은 처음이지] (0) | 2019.12.17 |
c++ 04 : 객체는 무엇으로 구성되는가? [ 클래스와 객체 / 어서와c++은 처음이지] (0) | 2019.12.17 |