정체불명의 모모

[ C / C++ ] malloc( ) 와 new 의 차이점 본문

프로그래밍(c++)

[ C / C++ ] malloc( ) 와 new 의 차이점

정체불명의 모모 2021. 7. 5. 00:23

최근 면접에서 대답 하지 못했던 부분에 대해 공부를 해보았습니다.

평소에 크게 신경쓰지 못했던것 이었는데, 

더 근본적인 부분들을 신경써보게 되는 계기가 되었다.

 

질문 : 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( ) 로 컴파일 했을 경우

Point::기본 생성자의 호출이 1번 있다.

 


▷ new키워드로 메모리 할당을 할 경우

: new 키워드를 붙여서 메모리를 할당해 준다.(매우매우 간단스)

template <typename T>
T* Arr = new T[arrSize];	//arrSize = 10;

▷ new키워드로 컴파일 했을 경우 ( 그저 위의 코드에서 #define 부분만 주석 처리 해주면 된다.)

Point::기본 생성자의 호출이 11번 있다.


위의 컴파일 결과를 보면 확실히 다르다는 것을 느낄 수 있다.

차이점

ㆍ malloc( ) 는 자료형 크기만큼 메모리만을 할당을 하고 생성자를 불러오고 있지 않다.

 

ㆍ new 키워드는 자료형 크기 만큼 메모리 할당을 해주고, 배열의 수 만큼 객체를 채워 넣어 생성자를 불러주고 있다.

     그렇기에 메모리 할당하는 부분에 있어서 10번의 생성자가 호출된 것 이다.

     (할당과 동시에 초기화 가능)

 

그럼 C++에서는 왜 new 와 delete 란 연산자를 이용해 메모리를 할당 해제 해주는 걸까?(인터넷 리서칭)

: C언어에서 사용한 malloc는 함수이기 때문에 C언어의 문법에 포함되지 않습니다.

  그냥 C언어 문법(컴파일러가)이 만들어진 이후에 추가적으로 만들어진 함수일 뿐입니다.

  그래서 malloc 함수와 컴파일러는 서로간의 문법적으로 약속된 부분이 없어서 매개변수나 형 변환 그리고 sizeof 연산자를 

  사용해서 표현을 할 수밖에 없습니다.

   하지만, new 연산자는 연산자이기 때문에 컴파일러와 문법 형식을 약속하였습니다.

  그래서 컴파일러와 약속된 문법을 사용하면 정해진 방식으로 처리해 주기 때문에 malloc 함수보다 좀더 단순한 표현이 가능합니다.

  (가독성이 좋고 편리함)

 

 그럼 malloc( ) 와 new 연산자 어느것이 더 빠를까?

그것은 나로써는 정확히 모르겠지만, new 연산자 안에 결국 malloc 함수를 호출한다고 알고 있다.

  그렇기에 malloc( )가 더 빠르다는 말이 많다.(정확한것은 실험을 한번 해봐야 겠다.)

  코드의 사용법에 맞춰 둘중 하나를 선택해 사용하면 훨씬 효율적인 코드가 될 것 같다.

 


매우 흥미로운 공부였던것 같다.

점점 가깝고도 멀게 느껴지는 C++...

좀 더 친해지고 싶다. ㅡㅜ

 

 

 

(혹시... 깃허브에 코드를 올려 놓았으니.. 보실분들은..)

https://github.com/MOMO320/Algorithm-C-/tree/master/Vector

 

MOMO320/Algorithm-C-

Contribute to MOMO320/Algorithm-C- development by creating an account on GitHub.

github.com

Comments