Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

any one have the help file for memproof 0950 ? 3

Status
Not open for further replies.

CADTenchy

Technical User
Dec 12, 2007
237
GB

Wondering if anyone has it, could they link to it for me?

All the search hits seem to have long expired...Thanks.

BTW, where is everyone?


Steve (Delphi 2007 & XP)
 
Or doing other things than Delphi (I just put together an older computer that was a garage sale find and got it working - took most of the last 3 days or so)...

But I got a project I need to try and finish up (and find that other one I promised too).

----------
Measurement is not management.
 

Checked out that 948 link. No Help file in there too.

Does one actually exist?

Or is there an instructions page still lurking?

I've ran it, and it says I have one area of virtual memory not freed, but other than that I'm stymied.


Steve (Delphi 2007 & XP)
 
memproof is telling me this:
memproof.gif


As I know nothing really of freeing memory (other than I have tried to be methodical and release everything I use),

I don't know if this is normal or needs attention?

Looking in VirtualFree, it seems I need to pass some parameters. Not really sure on that either.

Steve (Delphi 2007 & XP)
 
stop this nonsense.

what delphi version are you using?

if you have D2006 or up (I assume you have 2007) you can put this in your .dpr file (ebfore application.initialize) :

ReportMemoryLeaksOnShutdown := DebugHook <> 0;

this will enable the memorymanager to tell you if there were memory leaks after you stop the application.

Keep me posted...

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Yes I have 2007.

Done that and got this:
memleak1.gif


I can look for the stringlist ones fairly easy I guess, but the others?


Steve (Delphi 2007 & XP)
 
As I know nothing really of freeing memory (other than I have tried to be methodical and release everything I use)

show us some code, you're obviously doing something wrong here...


-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Well, on my main form for example I have a bunch of xxxx.free statements in the FormDestroy procedure.

I've tried to be pretty careful, where I use a save dialog, I'm (trying to at least) free that up too:

Code:
saveDialog := TSaveDialog.Create(self); 
saveDialog.Title := 'Choose name to save as';  
saveDialog.InitialDir := RootDir + '/logs';  
saveDialog.Filter := 'log files (*.ybb)|*.ybb'; 
saveDialog.DefaultExt := 'ybb';  
saveDialog.FilterIndex := 1;  starting filter type
if saveDialog.Execute   
  then
    begin
    MyFilename := ExtractFileName (saveDialog.FileName); 
    end
  else
    begin
    ShowMessagePos('Please enter a filename to save the log',(Self{MainForm}.Width Div 2) + Self{MainForm}.Left - 80,(Self{MainForm}.Height Div 2) + Self{MainForm}.Top - 50);
    exit;
    end;

  saveDialog.Free;

I've found two un-freed stringlists on a secondary form now.

I still have the line above added to the dpr file, but I'm not seeing the unexpected memory leak warning come up now.

Would two un-freed stringlists be the cause of all the errors above?


Steve (Delphi 2007 & XP)
 

Answered my last question myself by commenting out a free statement. (Answer was yes)

Do I need to remove the statement:

ReportMemoryLeaksOnShutdown := DebugHook <> 0;
(Thanks Daddy for this)

from my project dpr when I have finished writing it, or can I leave there with no effect on the compiled exe?

Thanks Daddy.


Steve (Delphi 2007 & XP)
 
one golden rule when you create and free things in a function/procedure: make sure your objects get freed, even if something bad happens.

take this code example:
Code:
function NotGood;

var StrList : TStringList;

begin
 StrList := TStringList.Create;
 StrList[1] := 'BOOM!'
 FreeAndNil(StrList);
end;

in this example the StrList[1] line will cause an exception and FreeAndNil will never be called -> we got ourselves a memory leak.
let's improve our function:

Code:
function BetterButStillNotGood;

var StrList : TStringList;

begin
 try
  StrList := TStringList.Create;
  StrList[1] := 'BOOM!'
 finally
  FreeAndNil(StrList);
 end;
end;

here the try..finally block will catch the exception and call the FreeAndNil part. BUT:
if for some reason, we are out of memory, the
StrList := TStringList.Create; line will fail.
in that case Delphi will automically call the destructor of the object. this means that our FreeAndNil line will try to free memory that is already released -> we have again an AV.

so we get to this:
Code:
function Good;

var StrList : TStringList;

begin
 StrList := TStringList.Create;
 try
  StrList[1] := 'BOOM!'
 finally
  FreeAndNil(StrList);
 end;
end;

that's about it, I hope you understand what I'm trying to explain here :)

from my project dpr when I have finished writing it, or can I leave there with no effect on the compiled exe?
you can leave it in the compiled exe. the DebugHook <> 0; statement will only be true when you run the program under delphi.


Cheers,
Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 

Thanks Daddy, I will indeed apply that my procedures where applicable.
I'll also change my StringList.Frees to FreeAndNil()s.

I have a few stringlists which I need available to several procedures, and a couple across forms.

I'm freeing these up in FormDestroy procedures.
I assume there is no better way?


Steve (Delphi 2007 & XP)
 
I tend to create my resources I need across the whole application in FormCreate of the main form and destroy them in FormDestroy. This to keep an easy overview.

there is an other way: Interfaces

the funny thing with interfaces is that when the object is no longer referenced (=used) it destroys itself.

quick example:

Code:
unit StringListInterface;

interface

uses
  SysUtils,
  Classes,
  SyncObjs;

type
  IIStringList = interface
  ['{344B711B-FBB2-473B-A864-F5D0ABB7A8F8}']
    function List : TStringList;
  end;

  TIStringList = class(TInterfacedObject, IIStringList )
  public
    StringList : TStringList;
    function List : TStringList;
    constructor Create;
    destructor Destroy; override;
  end;

implementation

constructor TIStringList .Create;
begin
 StringList := TStringList.Create;
end;

destructor TIStringList .Destroy;
begin
 FreeAndNil(StringList);
 inherited;
end;

function TIStringList .List : TStringList;
begin
 Result := StringList;
end;

end.

what I do above is encapsulate a TStringList inside an interface. Now you may ask, what is the added value of this extra code?

let me give you an example:

Code:
uses StringListInterface;

procedure TestStringListInterface;

var IStringList : IIStringList;

begin
 IStringList := TIStringList.Create;
 IStringList.List.Add('test');
end;

this code will NOT generate a memory leak because when the TestStringListInterface ends the IStringList variable is no longer referenced and will call the destructor (and will free it's internal stringlist object).
you can always force the destructor by setting the variable to nil:

Code:
uses StringListInterface;

procedure TestStringListInterface;

var IStringList : IIStringList;
    StringList : TStringList;

begin
 IStringList := TIStringList.Create;
 StringList := IStringList.List;
 StringList.Add('this works');
 IStringList :=  nil; // this will call the destructor
 StringList.Add('this will generate an AV'); //Stringlist points to and object that no longer exists
end;

Does this makes sense to you?

Cheers,
Daddy


-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
The define in Create and kill in Destroy is much more along the lines I understand, and am doing.

To be honest I don't completely follow the interfaces method.
I think I would tie myself in knots with that one.

Where does the hex number come from, out of interest?




Steve (Delphi 2007 & XP)
 
Where does the hex number come from, out of interest?

it is called a GUID (google it)
think of it as a unique number that is assigned to the interface. you can generate one in delphi with CTRL+SHIFT+g.

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top