C++ builder的内存储器释放: [ 自己添加public成员, 构造函数中new ]

C++ builder的内存释放: [ 自己添加public成员, 构造函数中new ]
本帖最后由 zoxoj 于 2013-10-22 11:04:46 编辑
本人非计算机专业。使用c++ buider XE2做个小程序。用来计算和画图。遇到如下问题,特此请教。

(1) 代码中添加控件:在 Unit1.h文件中的TForm1类的声明中加入了一个控件TButton *btnPrep,为public成员; 在Unit1.cpp文件中的TForm1::TForm1()中使用了 btnPrep = new TButton(this); btnPrep->Parent = this; 那么需不需要在TFrom1::OnDestroy()中使用 delete btnPrep;

(2) 构造函数中分配内存:程序中使用了TChart控件(TChart *chart)。添加方法和以上的做法一致(chart问TFrom1类的public成员)。在TFrom1::OnDestroy()中释放内存使用:delete chart; 和 delete[] chart; 均能通过编译。我应该使用哪个?

(3) TList类的构造函数不能指明ower; 即: list = new TList(); 释放list是不是有什么讲究。PS:list 也是TFrom1的public成员,其做法和(1)一致。

(4) 如何能看出我的程序是不是内存泄露了呢?


具体做法:

////// file: Unit1.h ///////////
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall OnDestroy(TObject *Sender);
private: // User declarations
public: // User declarations

TButton *btnPrep;  // <----- 注意这里
TChart *chart      // <----- 注意这里

__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif



在Unit.cpp文件的TForm1::TForm1()函数中使用了new, 具体做法:


/////////////// File Unit.cpp ////////////////////////
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
btnPrep = new TButton(this); // <----- 注意这里
btnPrep->Parent = this;      // <----- 注意这里
chart = new TChart(this);    // <----- 注意这里
chart->Parent = this;        // <----- 注意这里
}



在Unit.cpp文件的TForm1::OnDestroy()函数中使用了delete释放内存, 具体做法:

void __fastcall TForm1::OnDestroy(TObject *Sender)
{
delete btnPrep;              // <----- 注意这里
delete chart;
 /* delete[] chart; */       // <----- 注意这里, delete[] chart 可以通过编译.
}



[end]
内存泄露 C++ builer  TList TChart

------解决方案--------------------
(1) 代码中添加控件:在 Unit1.h文件中的TForm1类的声明中加入了一个控件TButton *btnPrep,为public成员; 在Unit1.cpp文件中的TForm1::TForm1()中使用了 btnPrep = new TButton(this); btnPrep->Parent = this; 那么需不需要在TFrom1::OnDestroy()中使用 delete btnPrep;

理论上是不需要的,可视化控件指定了owner后,会被owner释放

(2) 构造函数中分配内存:程序中使用了TChart控件(TChart *chart)。添加方法和以上的做法一致(chart问TFrom1类的public成员)。在TFrom1::OnDestroy()中释放内存使用:delete chart; 和 delete[] chart; 均能通过编译。我应该使用哪个?

两种都可,建议用第一种[]是针对数组用的。

(3) TList类的构造函数不能指明ower; 即: list = new TList(); 释放list是不是有什么讲究。PS:list 也是TFrom1的public成员,其做法和(1)一致。

TList不是可视化组件用(2)的方法

(4) 如何能看出我的程序是不是内存泄露了呢?
用内存泄露工具检测如:codeguard,也可长时间运行用任务管理器看内存增加情况
------解决方案--------------------
(1) 既然你显式的使用new创建了一个对象,那么严谨一些,应该在结束的时候用delete来销毁这个对象,尽管在VCL,创建组件时如果指定了有效的Onwer,那么Onwer会负责释放这个组件,但是我还是建议new和delete配对使用。

(2) 同(1)中的理论,new和delete配对,new []要和delete []配对。你的chart是用new创建的,那么就用delete来销毁。delete []是用来销毁数组的。

(3) TList对象,用new创建,用delete来销毁。

(4) 书写代码的时候就要严谨一些,注意new和delete配对。另外可以找一些辅助工具来检测内存泄露。当然了,有伪大牛说:即使有内存泄露也不怕,当应用程序结束的时候,整个进程占用的资源就回收了。从抬杠学的角度来看,这话说的也对。
------解决方案--------------------
C++ builder的内存储器释放: [ 自己添加public成员, 构造函数中new ]
------解决方案--------------------
关于 delete 与 delete []
如果不匹配,可能 codeguard 会错报的。如果不用 codeguard 之类的来做内存监测,那个对于 析放单个实例来说,一般应该没区别。不过,还是建议严格匹配,因为严格匹配总是正确的,我可不想我的代码引发其他异常。

------解决方案--------------------
(1) 不需要...以動態建立窗口為例 :
TForm1 *Form1; // 主窗口
TForm2 *TestFormA; // 運行生命期與主窗口相依

// ---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
// 以 VCL 機制...當主窗口 Destroy 時...TestFormA 連帶被釋放
TestFormA = new TForm2(this);
}

// ---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)