|
장성호님과 워프님께서 작성하신 글인데요.
무단으로 퍼왔는데... 문제가된다면 바로 삭제하겠습니다.
급해서 여쭤봅니다... FREE된다는게 구체적으로 어덯게된다는거죠? 잘몰라서그럽니다.
쉽게 설명해주시면 감사하겠습니다.
그리고 핸들러로 delete를하는데 소스대로 프로그램을 만들어보았으나 그래도 access-violation 오류가
납니다. 방법좀알려주세요 부탁합니다.
//////////////////////////////////////////////////////////////////////////////////////////////////////
그 객체에서 발생하는 이벤트에 해당 객체를 메모리에서 제거해버리면..
거의 대부분의 경우에 access-violation이 날것입니다.
아래의 경우 일부러 삭제하지 않아도 this인 Form1이 free될때 동적생성한 button도 자동 소멸되니
굳이 해주지 않아도 됩니다만..
님께서 해당 버튼을 클릭했을때 자동으로 종료하고 싶으면?
버튼 클릭이벤트에서 객체를 free하시면 안되구..
해당이벤트에 비동기 메세지를 보내서 처리하던지..
아니면.. 어떤 flag를 설정해줘서..
해당 객체(button)에서 발생하는 이벤트가 아닌
다른이벤트에서 delete해야 합니다.
샘플입니다.
?1
2
3
4
5
6
7
8
9
10
11 #define WM_USER+1 DELELE_OBJECT
void __fastcall TForm1::clsevent(TObject* sender)
{
PostMessage(this->Handle,DELELE_OBJECT,sender,0);
}
//-----------------------------------------------------
void __fastcall TForm1::DeleteObjectHandler(TMessage &Msg)
{
TButton *btn=(TButton *)Msg.WParam;
if(btn)delete btn;
}
그럼..
워프 님이 쓰신 글 :
: sample입니다.
: unit1.cpp 내용
: /***********************시작********************************
:
: #include <vcl.h>
: #pragma hdrstop
:
: #include "Unit1.h"
: //---------------------------------------------------------------------------
: #pragma package(smart_init)
: #pragma resource "*.dfm"
: TForm1 *Form1;
:
: TButton* cls; // TButton 포인터 생성
: //---------------------------------------------------------------------------
: __fastcall TForm1::TForm1(TComponent* Owner)
: : TForm(Owner)
: {
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::FormCreate(TObject *Sender)
: {
: cls = new TButton(this);
:
: cls->Caption = "동적생성 버튼";
: cls->Left = 25;
: cls->Top = 25;
: cls->Parent = this;
:
: cls->OnClick = clsevent; //OnClick 이벤트에 unit1.h에 선언한 clsevent 이벤트를 맵핑
:
: }
:
: void __fastcall TForm1::clsevent(TObject* sender){
: ShowMessage(sender->ClassName());
:
: delete sender;
: }
: ***********************끝*********************************/
:
: unit1.h 내용
:
: /******************시작***********************************
: class TForm1 : public TForm
: {
: __published: // IDE-managed Components
: void __fastcall FormCreate(TObject *Sender);
: private: // User declarations
: public: // User declarations
: __fastcall TForm1(TComponent* Owner);
: void __fastcall clsevent(TObject *Sender); // 이벤트 추가
: };
: //---------------------------------------------------------------------------
: extern PACKAGE TForm1 *Form1;
: //---------------------------------------------------------------------------
: **************************끝*******************************/
:
: 이벤트 등록하고, Onclick 이벤트랑 맵핑 한다음 넘겨온 (TButton*) 을 제거(자기자신) 합니다.
:
:
: 장성호 님이 쓰신 글 :
: : 이벤트에서 객체를 delete하면 안되는 이유는?
: :
: : 아래 코드를 보면
: : 님께서 Calender의 OnClick이벤트에서 Calenter객체를 delete하였습니다.
: : OnClick에 연결한 calendarEvent 라는 메소드는 새로 생성한 TMonthCalendar 클래스에서 호출되는것입니다.
: :
: : 이벤트가 호출된후에 Calender 객체 멤버에 대한 접근이 있는데.. 객체를 지워버리면.. access violation이 날수 밖에 없죠
: :
: : vcl컴포넌트의 자동 소멸은?
: : vcl객체의 자동 소멸은 .. 크게 2가지로 분류됩니다.
: :
: : 대표적은 것은 객체를 생성할때 넘겨준 첫번째 인지 Owner 라는 놈에 달려있습니다.
: : Owner가 free될때 자신을 owner로 가지고 있는 모든 Component를 free시킵니다.
: :
: : 아래코드에서는 calender객체를 생성하면서 Owner로 this즉 Form1을 넘겨줬으므로
: : Form1이 free될때 calender도 자동으로 free되는것입니다.
: :
: : 두번째는 Control의 경우 parent가 free될때 자동 free됩니다.
: : 아래코드에선 calender의 parent로 Form1을 주었기 때문에 Form1이 free될때 자동으로 free되는데요
: : 만약 calender를 Panel위에 올렸으면 Panel이 free될때 자동으로 calender도 free됩니다.
: :
: : 제생각은..
: : 어쨌든 제 생각은 ..
: : 위와같이 Bitbtn이 click될때마다 Calender를 동적생성하는 방법보다
: :
: : 하나 미리 생성해놓구...(디자인타임에 생성해도 되구요)
: : 필요없으면 visible=false해두시면 될것 같습니다.
: :
: : 객체의 free는 프로그램 종료될때 자동으로 되게 하구요
: :
: :
: : 그럼..
: :
: :
: :
: :
: :
: : 동철이 님이 쓰신 글 :
: : : 폼 하나에다 버튼하나가 있고 그 버튼을 클릭하면 달력컴포넌트(TMonthCalendar)가 뜨게 합니다. 거기서 날짜정보를 받고 이 컴포넌트를 닫으려고 다음과 같이 해주니깐 access violation error가 납니다.
: : :
: : :
?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 : : : void __fastcall TForm1::BitBtn1Click(TObject *Sender)
: : : {
: : : calendar = new TMonthCalendar(this);
: : : calendar->Parent = Form1;
: : : calendar->Left = 68;
: : : calendar->Top = 240;
: : : calendar->Width = 60;
: : : calendar->Height = 70;
: : :
: : : calendar->OnClick = calendarEvent;
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : : void __fastcall TForm1::calendarEvent(TObject *Sender)
: : : {
: : : TDateTime pdate;
: : : AnsiString str;
: : : pdate = calendar->Date;
: : : str = pdate.DateString();
: : : ShowMessage(str.SubString(1,4));
: : : ShowMessage(str.SubString(6,2));
: : : ShowMessage(str.SubString(9,2));
: : : delete calendar; // <-- 이 부분 실행 후 에러 발생.
: : : }
: : :
: : : 저도 new 한 함수와 delete한 함수가 서로 다른데서 찜찜한 감이 오긴 왔습니다만...
: : :
: : : 보통 컴포넌트를 동적으로 불러내고 메모리에서 삭제하려면 이런 식으로 하면 안되는 건가요?
: : :
: : : 아예 그냥 프로그램에서 알아서 힙 메모리에서 해제하도록 delete 안하는게 나을까요?
|