C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[530] placement new 의 사용.
김태선 [jsdkts] 6306 읽음    2005-12-05 15:06
#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

+ -

관련 글 리스트
530 placement new 의 사용. 김태선 6306 2005/12/05
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.