BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Construction problem

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Johan Anderlund
Guest





PostPosted: Sat Mar 31, 2007 11:54 pm    Post subject: Construction problem Reply with quote



Hi

---
I have a frame class in unit A:

TfrmLookup = class(TFrame)
...
private
{ Private declarations }
public
{ Public declarations }
end;

---
I have two frame objects in Unit B, where I also create the objects.

var
Till_Lookup1: TfrmLookup;
Till_Lookup2: TfrmLookup;

procedure hereicreatetheframe
begin
Till_Lookup1 := TfrmLookup.Create(frmMain);
Till_Lookup1.Parent := frmMain;
Till_Lookup2 := TfrmLookup.Create(frmMain);
Till_Lookup2.Parent := frmMain;
end;

---
I have the mainform class and object, frmMain, in unit C.

TfrmMain = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

---
Problem is the following error I get when creating Till_Lookup2 in Unit
B: "A component named frmLookup already exists".

What do I do wrong and what do I have to do to do this correctly?
I want all my objects to be freed automatically when mainform is destroyed.

// Johan
Back to top
Peter Below (TeamB)
Guest





PostPosted: Sun Apr 01, 2007 2:52 am    Post subject: Re: Construction problem Reply with quote



Johan Anderlund wrote:

Quote:
Hi

---
I have a frame class in unit A:

TfrmLookup = class(TFrame)
...
private
{ Private declarations }
public
{ Public declarations }
end;

---
I have two frame objects in Unit B, where I also create the objects.

var
Till_Lookup1: TfrmLookup;
Till_Lookup2: TfrmLookup;

procedure hereicreatetheframe
begin
Till_Lookup1 := TfrmLookup.Create(frmMain);
Till_Lookup1.Parent := frmMain;
Till_Lookup2 := TfrmLookup.Create(frmMain);
Till_Lookup2.Parent := frmMain;
end;

---
I have the mainform class and object, frmMain, in unit C.

TfrmMain = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

---
Problem is the following error I get when creating Till_Lookup2 in
Unit B: "A component named frmLookup already exists".

What do I do wrong and what do I have to do to do this correctly?

procedure hereicreatetheframe
begin
Till_Lookup1 := TfrmLookup.Create(frmMain);
Till_Lookup1.Parent := frmMain;
Till_Lookup1.Name := ''; <===
add this
Till_Lookup2 := TfrmLookup.Create(frmMain);
Till_Lookup2.Parent := frmMain;
Till_Lookup2.Name := ''; <===
and this
end;

The VCL is designed to require all components owned by another
components to have unique names. That comes from the mechanism the VCL
uses to identify the fields of a design-time class (like a form) into
which it should store the object
reference for a component created at run-time from the form resource.
In your case the form does not have any published fields for the frames
you create, so the names can be set to empty.

--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
Back to top
Johan Anderlund
Guest





PostPosted: Sun Apr 01, 2007 4:38 am    Post subject: Re: Construction problem Reply with quote



Thanks, I managed to free over 500 resources that caused memory leaks :)

I have a follow-up question on some remaining stuff to free.
My frame contains this:

TfrmLookup = class(TFrame)
trnLookup: TIBTransaction;
qryLookup: TIBQuery;
dsLookup_Link: TDataSource;
dspLookup: TDataSetProvider;
cdsLookup: TClientDataSet;
dsLookup: TDataSource;
private
{ Private declarations }
public
{ Public declarations }
destructor Destroy; override;
end;

// trying to free used mem
destructor TfrmLookup.Destroy;
begin
qryLookup.SQL.Text := '';
cdsLookup.IndexDefs.Clear;
cdsLookup.IndexName := '';
cdsLookup.FieldDefs.Clear;
cdsLookup.Fields.Clear;
cdsLookup.Params.Clear;
qryLookup.Fields.Clear;
qryLookup.Params.Clear;
inherited;
end;
---
When I create a frame I have this code:

Rooms_Lookup := TfrmLookup.Create(frmMain);
Rooms_Lookup.Name := '';

Rooms_Lookup.qryLookup.SQL.Text := 'select * ' +
'from GET_ROOMS';
Rooms_Lookup.cdsLookup.IndexDefs.Add('NameAsc', 'NAME', []);
Rooms_Lookup.cdsLookup.IndexDefs.Add('NameDesc', 'NAME', [ixDescending]);
Rooms_Lookup.cdsLookup.IndexName := 'NameAsc';

...
Rooms_Lookup.cdsLookup.Open;

---
MemProof gives me this:
SysAllocStringLen("GET_ROOMS"."ID_ROOM",21)
SysAllocStringLen("GET_ROOMS"."NAME",21)
SysAllocStringLen("GET_ROOMS"."ID_ROOM",21)
SysAllocStringLen("GET_ROOMS"."NAME",21)

I wrote a destructur and tried to clear stuff, but without success.
Anyone have a clue what could cause the memory leak?

// Johan


Peter Below (TeamB) wrote:
Quote:
Johan Anderlund wrote:


Hi

---
I have a frame class in unit A:

TfrmLookup = class(TFrame)
...
private
{ Private declarations }
public
{ Public declarations }
end;

---
I have two frame objects in Unit B, where I also create the objects.

var
Till_Lookup1: TfrmLookup;
Till_Lookup2: TfrmLookup;

procedure hereicreatetheframe
begin
Till_Lookup1 := TfrmLookup.Create(frmMain);
Till_Lookup1.Parent := frmMain;
Till_Lookup2 := TfrmLookup.Create(frmMain);
Till_Lookup2.Parent := frmMain;
end;

---
I have the mainform class and object, frmMain, in unit C.

TfrmMain = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

---
Problem is the following error I get when creating Till_Lookup2 in
Unit B: "A component named frmLookup already exists".

What do I do wrong and what do I have to do to do this correctly?


procedure hereicreatetheframe
begin
Till_Lookup1 := TfrmLookup.Create(frmMain);
Till_Lookup1.Parent := frmMain;
Till_Lookup1.Name := ''; <===
add this
Till_Lookup2 := TfrmLookup.Create(frmMain);
Till_Lookup2.Parent := frmMain;
Till_Lookup2.Name := ''; <===
and this
end;

The VCL is designed to require all components owned by another
components to have unique names. That comes from the mechanism the VCL
uses to identify the fields of a design-time class (like a form) into
which it should store the object
reference for a component created at run-time from the form resource.
In your case the form does not have any published fields for the frames
you create, so the names can be set to empty.
Back to top
Stefan Meisner
Guest





PostPosted: Sun Apr 01, 2007 9:28 pm    Post subject: Re: Construction problem Reply with quote

Hello!

Quote:

I wrote a destructur and tried to clear stuff, but without success. Anyone
have a clue what could cause the memory leak?

To find memory leaks you could try my software DDServer
which you can get here: www.delphi-online.at

Regards
Stefan
Back to top
Peter Below (TeamB)
Guest





PostPosted: Sun Apr 01, 2007 9:52 pm    Post subject: Re: Construction problem Reply with quote

Johan Anderlund wrote:

Quote:
I have a follow-up question on some remaining stuff to free.
My frame contains this:

TfrmLookup = class(TFrame)
trnLookup: TIBTransaction;
qryLookup: TIBQuery;
dsLookup_Link: TDataSource;
dspLookup: TDataSetProvider;
cdsLookup: TClientDataSet;
dsLookup: TDataSource;
private
{ Private declarations }
public
{ Public declarations }
destructor Destroy; override;
end;

// trying to free used mem
destructor TfrmLookup.Destroy;
begin
qryLookup.SQL.Text := '';
cdsLookup.IndexDefs.Clear;
cdsLookup.IndexName := '';
cdsLookup.FieldDefs.Clear;
cdsLookup.Fields.Clear;
cdsLookup.Params.Clear;
qryLookup.Fields.Clear;
qryLookup.Params.Clear;
inherited;
end;

That should not be necessary. If the components referred to in your
destructor are owned by the frame they will do all this on their own
when they get destroyed. But if you want to do it, do it right <g>:
first close the query and the cds before you begin to disembowel them.

Quote:
---
When I create a frame I have this code:

Rooms_Lookup := TfrmLookup.Create(frmMain);
Rooms_Lookup.Name := '';

Rooms_Lookup.qryLookup.SQL.Text := 'select * ' +
'from GET_ROOMS';
Rooms_Lookup.cdsLookup.IndexDefs.Add('NameAsc', 'NAME', []);
Rooms_Lookup.cdsLookup.IndexDefs.Add('NameDesc', 'NAME',
[ixDescending]); Rooms_Lookup.cdsLookup.IndexName := 'NameAsc';

...
Rooms_Lookup.cdsLookup.Open;

---
MemProof gives me this:
SysAllocStringLen("GET_ROOMS"."ID_ROOM",21)
SysAllocStringLen("GET_ROOMS"."NAME",21)
SysAllocStringLen("GET_ROOMS"."ID_ROOM",21)
SysAllocStringLen("GET_ROOMS"."NAME",21)

SysAllocStringLen is a function from the OLE2.DLL, part of Windows COM
support. It is used by the Delphi RTL to manage memory for Widestring
types. From the names I would guess that the query allocates these
strings for the columns it retrieved from the dataset. If the
Widestrings stay allocated beyond the death of the component that
allocated them that would constitute a bug in said component, IMO.

--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
Back to top
Johan Anderlund
Guest





PostPosted: Mon Apr 02, 2007 12:56 am    Post subject: Re: Construction problem Reply with quote

Peter Below (TeamB) wrote:
Quote:
Johan Anderlund wrote:


I have a follow-up question on some remaining stuff to free.
My frame contains this:

TfrmLookup = class(TFrame)
trnLookup: TIBTransaction;
qryLookup: TIBQuery;
dsLookup_Link: TDataSource;
dspLookup: TDataSetProvider;
cdsLookup: TClientDataSet;
dsLookup: TDataSource;
private
{ Private declarations }
public
{ Public declarations }
destructor Destroy; override;
end;

// trying to free used mem
destructor TfrmLookup.Destroy;
begin
qryLookup.SQL.Text := '';
cdsLookup.IndexDefs.Clear;
cdsLookup.IndexName := '';
cdsLookup.FieldDefs.Clear;
cdsLookup.Fields.Clear;
cdsLookup.Params.Clear;
qryLookup.Fields.Clear;
qryLookup.Params.Clear;
inherited;
end;


That should not be necessary. If the components referred to in your
destructor are owned by the frame they will do all this on their own
when they get destroyed. But if you want to do it, do it right <g>:
first close the query and the cds before you begin to disembowel them.


---
When I create a frame I have this code:

Rooms_Lookup := TfrmLookup.Create(frmMain);
Rooms_Lookup.Name := '';

Rooms_Lookup.qryLookup.SQL.Text := 'select * ' +
'from GET_ROOMS';
Rooms_Lookup.cdsLookup.IndexDefs.Add('NameAsc', 'NAME', []);
Rooms_Lookup.cdsLookup.IndexDefs.Add('NameDesc', 'NAME',
[ixDescending]); Rooms_Lookup.cdsLookup.IndexName := 'NameAsc';

...
Rooms_Lookup.cdsLookup.Open;

---
MemProof gives me this:
SysAllocStringLen("GET_ROOMS"."ID_ROOM",21)
SysAllocStringLen("GET_ROOMS"."NAME",21)
SysAllocStringLen("GET_ROOMS"."ID_ROOM",21)
SysAllocStringLen("GET_ROOMS"."NAME",21)


SysAllocStringLen is a function from the OLE2.DLL, part of Windows COM
support. It is used by the Delphi RTL to manage memory for Widestring
types. From the names I would guess that the query allocates these
strings for the columns it retrieved from the dataset. If the
Widestrings stay allocated beyond the death of the component that
allocated them that would constitute a bug in said component, IMO.


After some debugging I found out that gnugettext is allocating
widestrings in LoadResString, when I open my clientdataset and does not
free it when closing.

I don't know how/what to free?

Any ideas?

// Johan
Back to top
Peter Below (TeamB)
Guest





PostPosted: Mon Apr 02, 2007 6:23 pm    Post subject: Re: Construction problem Reply with quote

Johan Anderlund wrote:

Quote:
SysAllocStringLen is a function from the OLE2.DLL, part of Windows
COM support. It is used by the Delphi RTL to manage memory for
Widestring types. From the names I would guess that the query
allocates these strings for the columns it retrieved from the
dataset. If the Widestrings stay allocated beyond the death of the
component that allocated them that would constitute a bug in said
component, IMO.


After some debugging I found out that gnugettext is allocating
widestrings in LoadResString, when I open my clientdataset and does
not free it when closing.

I don't know how/what to free?

Those are probably global Widestring instance. You can safely ignore
that leak, the memory is returned to the OS when the application
terminates, that just happens after your leak detector has become
disconnected.

--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.