new 연산자
new 연산자는 C++에서 특정 개체 타입을 동적할당하고 초기화하는데 사용한다.
placement new
표현식 : new (Address) Type (Initialize arguments);
이미 메모리 할당이 이루어진 주소 공간에 해당 타입으로 초기화할 때 사용한다. 주로 메모리 풀이나 가비지 컬렉터와 같은 응용에 사용된다. new 연산자를 이용하지만 실제로 동적 할당이 이루어지는 것이 아니며 실제 행동은 초기화만 진행된다.
segmentation fault가 발생한 경우 : 전달한 Address 주소가 유효하지 않은 메모리 주소 혹은 null 포인터일 경우 발생할 수 있다.
메모리 해제 : 힙 메모리의 경우 실제로 동적 할당을 수행한 주소를 가진 포인터를 삭제 시키는 것으로 해제하며 스택 메모리의 경우 따로 해제할 필요가 없다.
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <crtdbg.h>
#include <iostream>
using namespace std;
struct Complex
{
float Real;
float Img;
Complex()
:
Real(0.f), Img(0.f)
{}
Complex(float r, float i)
:
Real(r), Img(i)
{}
};
void Print(Complex* c)
{
printf("Complex 0x%p : (%.1f,%.1f)\n", c, c->Real, c->Img);
}
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
unsigned char buf[100];
printf("Buffer 0x%p\n", buf);
// using placement new
Complex* p1 = new(buf) Complex(1.f, 1.f);
Complex* p2 = new(buf + sizeof(Complex)) Complex(2.f, 2.f);
Complex* p3 = new(buf + 2 *sizeof(Complex)) Complex(3.f, 3.f);
Print(p1);
Print(p2);
Print(p3);
return 0;
}
buf라는 100 바이트 크기를 가진 지역 변수에 배열 처럼 Complex 구조체 3개를 초기화하는 방법을 보인다. 메모리가 연속적이므로 캐시에 유리하고 꼭 같은 타입을 초기화할 필요없이 메모리만 할당되어 있다면 여러 타입의 개체를 placement new를 사용하여 원하는 주소에 할당할 수 있다.
- 힙 메모리를 이용
힙 메모리를 이용해서도 개체를 할당할 수 있다.
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
std::unique_ptr<char[]> buffer(new char[100]);
char* pBuf = buffer.get();
printf("Buffer 0x%p\n", pBuf);
// using placement new
Complex* p1 = new(pBuf) Complex(1.f, 1.f);
Complex* p2 = new(pBuf + sizeof(Complex)) Complex(2.f, 2.f);
Complex* p3 = new(pBuf + 2 *sizeof(Complex)) Complex(3.f, 3.f);
Print(p1);
Print(p2);
Print(p3);
return 0;
}
'Advanced C++' 카테고리의 다른 글
[C++] 정규식 표현 std::regex으로 문자열 찾기 (0) | 2022.02.07 |
---|---|
[C++] 메모리 관리 (4) 정적 메모리 풀 (0) | 2021.10.10 |
[C++] 메모리 관리 (2) 힙 메모리 new/malloc/HeapAlloc/VirtualAlloc (0) | 2021.10.03 |
[C++] 메모리 관리 (1) Windows 메모리 관리 (0) | 2021.10.03 |
[C++] 멀티쓰레드 환경에서의 스마트 포인터 (0) | 2021.08.16 |