如何释放内存,源码已贴出。 (100分)

  • 主题发起人 chinesetree
  • 开始时间
C

chinesetree

Unregistered / Unconfirmed
GUEST, unregistred user!
应用程序:
unit UTestContact;

interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs,StdCtrls, XContact, ComCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
EditName: TEdit;
EditPhone: TEdit;
EditEMail: TEdit;
ButtonAdd: TButton;
ButtonRemove: TButton;
ButtonFind: TButton;
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonAddClick(Sender: TObject);
procedure ButtonRemoveClick(Sender: TObject);
procedure ButtonFindClick(Sender: TObject);
private
{ Private declarations }
FCurrentContact : IContact;
ContactList : IContactList;
Procedure UpdateCount( Count : Integer );
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
{$R *.DFM}

function ContactClass : TContactClass; external
'NewContactServer.dll';
function ContactListClass : TContactListClass; external
'NewContactServer.dll';
/****************************
procedure TForm1.FormCreate(Sender: TObject);
begin
FCurrentContact := Nil;
ContactList := ContactListClass.Create;
end;
/**************************

procedure TForm1.FormDestroy(Sender: TObject);
begin
ContactList.Free;
end;
/*********************************
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
FCurrentContact := ContactClass.Create( EditName.Text,
EditPhone.Text, EditEMail.Text );
ContactList.Add( FCurrentContact );
UpdateCount( ContactList.Count );
end;
****************************************/
procedure TForm1.ButtonRemoveClick(Sender: TObject);
begin
if( Assigned(FCurrentContact)) then
begin
ContactList.Remove( FCurrentCOntact);
UpdateCount( ContactList.Count );
end;
end;

procedure TForm1.ButtonFindClick(Sender: TObject);
var
I : Integer;
begin
for I := 0 to ContactList.Count - 1 do
if( ContactList.Phone = EditPhone.Text ) then
begin
FCurrentContact := ContactList;
EditName.Text := FCurrentContact.Name;
EditPhone.Text := FCurrentContact.Phone;
EditEMail.Text := FCurrentContact.EMail;
exit;
end;
MessageDlg( 'Contact phone number not found', mtInformation, [mbOK], 0);
end;

Procedure TForm1.UpdateCount( Count : Integer );
begin
StatusBar1.SimpleText := Format( 'Count: %d', [Count] );
end;

end.
程序如上:
当点击ButtonAdd后,ContactClass.Create( EditName.Text,
EditPhone.Text, EditEMail.Text );语句运行一次,
多次点击后,内存中存在多个实例,如果没有执行相应的
ButtonRemove退出时内存就会出错,
请问如何退出时释放[:)][?][?]
 
function ContactClass : TContactClass;
begin
result := TContact.Create('姓名','电话','地址');
////////////////////////
end;
function ContactListClass : TContactListClass;
begin
result := TContactList.Create;
////
end;
 
TO:jsxjd我又仔细看了源码,与DLL不关
是其中的ContactClass.Create( EditName.Text,
EditPhone.Text, EditEMail.Text )在做怪,
 
没有人回答[?][?][?][?]
 
使用single模式。
 
那個BUTTON上、
if Assigned(指針) then
exit
 
新手,不懂指针,能不能来个例子
 
不会吧,没有帮忙,这个问题该很常见哪
 
不大清楚TList中存在的对象,记录等在TList.Free之后是否自动释放
好像是没有吧,总是不放心,所以每次用了后都手工释放的,不过,直接List.Free
也没有出错过
for i:=List.Count-1 downto 0 do
List.Free;//或是dispose(Precord)
List.Free;
 
试了不行呀,出现EAccessViolation exception
 
你应做转化的ContactClass(ContactList).Free;//应该可以吧,
要不就是你的ContactClass或者ContactListClass有问题吧
 
TO:LGXing有没有兴趣读原码?
 
问题在这儿,
我先估计你的 ContactListClass 为一个 Tlist 类,这个类中包含的对象得由程序员自己释放
你多次用ADD生成多个对象后,
当时 FCurrentContact 指向的最后一个 CurrentContact 实例,
所以不管你 ReMove 多少次,都只是 ReMove 了ContactListClass中的一个对象
于是你的程序中还有很多个CurrentContact 对象,
当你在ContactListClass中还有很多CurrentContact 对象时Free ,所以就出错了
你用LGXing的代码试试。
另外,
procedure TForm1.FormDestroy(Sender: TObject);
begin
ContactList.Free;
ContactList:=Nil;//应加上这句
end;
 
楼上说的对,其实就是一个TList类,试了以后,不行,
例子来自<<delphi 6 应用开发指南>>,贴出另外的源码,
一、基类:
unit XContact;
// XContact.pas - Contains abstract implementation of a contact and contact list.
// Copyright (c) 2000. All Rights Reserved.
// by Software Conceptions, Inc. Okemos, MI USA (800) 471-5890
// Written by Paul Kimmel

interface
uses
classes;

type
IContact = class; // forward declaration
IContactList = class;
TContactClass = class of IContact;
TContactListClass = class of IContactList;
IContact = class
protected
function GetEMail: string; virtual; abstract;
function GetName: String; virtual; abstract;
function GetPhone: String; virtual; abstract;
procedure SetEmail(const Value: string); virtual; abstract;
procedure SetName(const Value: String); virtual; abstract;
procedure SetPhone(const Value: String); virtual; abstract;
public
constructor Create( const Name, Phone, EMail : String );
virtual;
property Name : String read GetName write SetName;
property Phone : String read GetPhone write SetPhone;
property EMail : string read GetEMail write SetEmail;
end;

IContactList = class
protected
function GetList : TList; virtual; abstract;
function GetContact( Index : Integer ) : IContact; virtual;
abstract;
procedure SetContact( Index : Integer; const Value : IContact);
virtual; abstract;
function GetCount : Integer; virtual; abstract;
public
constructor Create; virtual;
procedure Add( Contact : IContact ); virtual; abstract;
procedure Remove( COntact : IContact ); virtual; abstract;
property Contacts[Index : Integer] : IContact read GetContact
write SetContact; default;
property List : TList read GetList;
property Count : Integer read GetCount;
end;

implementation
{ IContactList }
constructor IContactList.Create;
begin
inherited;
end;
{ IContact }
constructor IContact.Create( const Name, Phone, EMail : String );
begin
inherited Create;
Self.Name := Name;
Self.Phone := Phone;
Self.EMail := EMail;
end;
end.
二、类方法的实现:
unit UImpContact;
// UImpContact.pas - Contains the implementation of contact and contact list
// Copyright (c) 2000. All Rights Reserved.
// by Software Conceptions, Inc. Okemos, MI USA (800) 471-5890
// Written by Paul Kimmel
interface
uses
XContact, Classes, SysUtils;
type
TContact = class(IContact)
private
FEMail : String;
FName : String;
FPhone : String;
protected
function GetEMail: string; override;
function GetName: String; override;
function GetPhone: String; override;
procedure SetEmail(const Value: string); override;
procedure SetName(const Value: String); override;
procedure SetPhone(const Value: String); override;

public
property Name : String read GetName write SetName;
property Phone : String read GetPhone write SetPhone;
property EMail : string read GetEMail write SetEmail;
end;

TContactList = class(IContactList)
private
FList : TList;
protected
function GetList : TList; override;
function GetContact( Index : Integer ) : IContact; override;
procedure SetContact( Index : Integer; const Value :IContact); override;
function GetCount : Integer; override;
public
constructor Create; override;
procedure Add( Contact : IContact ); override;
procedure Remove( COntact : IContact ); override;
destructor Destroy; override;
property Contacts[Index : Integer] : IContact read GetContact write SetContact;
property List : TList read GetList;
property Count : Integer read GetCount;
end;

implementation
{ TContact }

function TContact.GetEMail: string;
begin
result := FEMail;
end;

function TContact.GetName: String;
begin
result := FName;
end;

function TContact.GetPhone: String;
begin
result := FPhone;
end;

procedure TContact.SetEmail(const Value: string);
begin
FEmail := Value;
end;

procedure TContact.SetName(const Value: String);
begin
FName := Value;
end;

procedure TContact.SetPhone(const Value: String);
begin
FPhone := Value;
end;

{ TContactList }
constructor TContactList.Create;
begin
inherited;
FList := TList.Create;
end;

destructor TContactList.Destroy;
begin
while( FList.Count > 0 ) do
begin
TContact(FList.Items[0]).Free;
FList.Delete(0);
end;
FList.Free;

inherited;
end;

procedure TContactList.Add( Contact : IContact );
begin
FList.Add( Contact );
end;

procedure TContactList.Remove( Contact : IContact );
begin
FList.Remove( Contact );
end;

function TContactList.GetContact(Index: Integer): IContact;
begin
result := TContact(FList.Items[Index]);
end;

function TContactList.GetCount: Integer;
begin
result := FList.Count;
end;

function TContactList.GetList: TList;
begin
result := FList;
end;
procedure TContactList.SetContact(Index: Integer; const Value: IContact);
begin
FList.Insert( Index, Value )
end;
end.
三、Dll
library NewContactServer;
uses
ShareMem,
SysUtils,
Classes,
XContact in 'XContact.pas',
UImpContact in 'UImpContact.pas';
{$R *.RES}
function ContactClass : TContactClass;
begin
result := TContact;
end;
function ContactListClass : TContactListClass;
begin
result := TContactList;
end;
exports
ContactClass, ContactListClass;
begin
end.
谢谢~~~
 
看了代码,实现方法应该说是不好的(对于你要实现的功能)
你现有程序,释放只能是这样(不出错而已):
procedure TForm1.FormDestroy(Sender: TObject);
var
i:Integer;
begin
for i:=ContactList.Count -1 downto 0 do
ContactList.Remove(ContactList);
ContactList.Free;
end;
 
问题解决了,可不可以给出进一步的解释,分随后送到[:)][:)][:)][:)]
 
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
if assigned(FCurrentContact) then freeandnil(FCurrentContact);
////////////////////////////////////////////////////////////
FCurrentContact := ContactClass.Create( EditName.Text,
EditPhone.Text, EditEMail.Text );
ContactList.Add( FCurrentContact );
UpdateCount( ContactList.Count );
end;


在 form 的 OnDestroy 事件中也写上:
if assigned(FCurrentContact) then freeandnil(FCurrentContact);
 
谢谢大家[:)][:)][:)][:)]
领分了[:D][:D][:D]
 
多人接受答案了。
 
顶部