#include <new>
를 하고나면 new 로 생성되는 데이타 위치를 임의로 조정할 수도 있습니다.
보통 클래스 A 에 대해
A *a = new A;
라고 하면 힙영역에 데이타를 위한 메모리가 할당되고 그 번지가 되돌려 집니다.
하지만 new 시 원하는 위치를 지정할 수도 있습니다.
가령
byte abuf[sizeof(A)];
로 객체가 들어갈 위치를 잡고
A *a = new (abuf) A;
식으로 그 위치에 객체를 생성할 수 있습니다.
이걸 어디에 이용할까요?
가장 유용한 것은 객체 배열을 만들때입니다.
객체 배열이야
A a[100]; 식으로 생성해도 되지요.
하지만 만일 A 가 생성인자를 가지고 생략할 수 있는 방법이 없다면...
A a("i am a boy")[100];
또는
A *pA = new A("i am a boy")[100];
이런 문법이 C++에서는 통하지 않습니다.
하지만 new 위치지정자를 사용하면 간단히 해결됩니다.
대신 for 루프를 좀 돌려야 됩니다.
byte abuf[sizeof(A) * 100]; // 먼저 객체가 생성될 메모리 위치를 잡아주고
for(int c = 0; c < 100; c++)
new (abuf + sizeof(A) * c) A("i have number: ", c);
식으로 생성하는 것이 가능해 집니다.
엑세스는
A *pA = (A *)abuf;
식으로 캐스팅해서 하면 되겠죠.
그런데 문제는 VCL 스타일 클래스는 이게 안된다는데 있습니다.
VCL 스타일 클래스는 무조건 힙에 생성됩니다.
임의 메모리 위치를 지정해도 힙에 생성되어 있습니다.
VCL 스타일은 placement new 가 통하지 않습니다. ㅡㅡ;
아래는 그것을 확인할 수 있는 예제입니다.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <new>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void add(void *ptr)
{
ULONG p = (ULONG)ptr;
Form1->Memo1->Lines->Add(String().sprintf("%08X", p));
}
class A
{
char a;
public:
void put(int x)
{
Form1->Caption = x;
}
};
byte buf_str[sizeof(TStringList)];
void __fastcall TForm1::Button1Click(TObject *Sender)
{
byte buf[sizeof(TStringList)];
byte buf2[sizeof(A)];
add(buf);
add(buf2);
add(buf_str);
A *a = new(buf2) A;
add(a);
delete a;
TStringList *str = new(buf) TStringList; // 생성 위치를 어디를 지정해도 모두 힙에 생성됩니다.
add(str);
delete str;
TStringList *str2 = new TStringList;
add(str2);
delete str2;
}
제 컴의 실행결과:
0012F4AC // 스택 영역
0012F4EB
0046992C // 정적 메모리 영역
0012F4EB
00D62B60 // 힙영역
00D62B60
|