Solved

TStringList Freeing

Posted on 2003-11-07
23
346 Views
Last Modified: 2010-04-05
Hi everyone,

I know it is an easy question for you.  I am getting Access violation on freeing an object.

LineInfo := TStringList.Create;

Try
...Try to do something but somehow no line could be added to LineInfo.
Except
   showmessage('could not add line');
end;

LineInfo.Free;

Boundschecker is showing resource leak on LineInfo create even though no line could be added. When delphi tries to free it, it raises an exception, even though the object has not nil value.  How can I free this object once it is created and then if it fails to add any line?

Thanks.
0
Comment
Question by:mimran
  • 8
  • 4
  • 2
  • +2
23 Comments
 
LVL 26

Expert Comment

by:EddieShipman
ID: 9705738
This is the way to do it...

LineInfo := TStringList.Create;
try
  try
    ...Try to do something but somehow no line could be added to LineInfo.
  except
    showmessage('could not add line');
  end;
finally
  LineInfo.Free;
end;

0
 

Expert Comment

by:mece
ID: 9712887
above code must be like this

LineInfo := TStringList.Create;
try
  try
    ...Try to do something but somehow no line could be added to LineInfo.
  except
    showmessage('could not add line');
    raise;
  end;
finally
  LineInfo.Free;
end;
0
 

Author Comment

by:mimran
ID: 9715539
Hi,
I could not reply because of week end.  Thanks I will try these code right now..
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:mimran
ID: 9716297
I have located the problem.  I have one proc and one function.  Please see the code below:

function ReadSpec: Tstringlist;
var
    Lines: TSrintlist;
begin
       Lines := TStringList.Create;
       . . .
       Result := Lines;
      //I have to release Lines.
end;

procedure AddToBatch;
var
    LineInfo: TStringList;
begin
    LineInfo := TStringList.Create;

    Try
        //...do something
        LineInfo := ReadSpec;
       
       if LineInfo.Count = 0 then
             MessageDlg('No valid lines were found for order: '+OrderNo, mtInformation, [mbOK], 0);
       .....
     Except
             showmessage('could not add line');
     end;
     
     LineInfo.Free;   FreeAndNil(LinesInfo);
end;

I was thinking that "Lines" was being returned by "ReadSpec" func after freeing it.  But it is not.  The problem is that in ReadSpec function, Lines object is to be returned by "Result := Lines", and then it has to be released.  But If I add a line "Lines.Free" under 'Result := Lines', then the "result" has no value passed to LineInfo in AddtoBatch, which caused Access Violation on "LineInfo.Count".  Can you tell how I can release "Lines" object in "ReadSpec" function without hurting the "Result := Lines"?

Thanks
0
 

Expert Comment

by:mece
ID: 9716964
you are wrong here,

procedure AddToBatch;
var
    LineInfo: TStringList;
begin
    Try
        //...do something
        LineInfo := ReadSpec;
       
       if LineInfo.Count = 0 then
             MessageDlg('No valid lines were found for order: '+OrderNo, mtInformation, [mbOK], 0);
       .....
     Except
             showmessage('could not add line');
     end;
     
     LineInfo.Free;   FreeAndNil(LinesInfo);
end;
(Above code is what yo want, not change readspec)

you can change the second code with that or
first func like that

procedure ReadSpec(var LineInfo : TStringList)
var
    Lines: TSrintlist;
begin
       Lines := TStringList.Create;
       . . .
      //I have to release Lines.
end;


procedure AddToBatch;
var
    LineInfo: TStringList;
begin
    Try
        //...do something
        ReadSpec(LineInfo );
       
       if LineInfo.Count = 0 then
             MessageDlg('No valid lines were found for order: '+OrderNo, mtInformation, [mbOK], 0);
       .....
     Except
             showmessage('could not add line');
     end;
     
     LineInfo.Free;   FreeAndNil(LinesInfo);
end;

if you create both functions then one of them makes the problem.
0
 

Expert Comment

by:tuzai
ID: 9729250
I think the 《Mastering the delphi7》has discussed this question more detail.
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 9730838
You do not have to free the stringlist created in the function ReadSpec.
0
 

Author Comment

by:mimran
ID: 9732128
If I create an object without 'Self' or anything, delphi won't release it, rather you have to release it.  Anyway I have fixed this problem by making this object as private in the form, so I don't have to define/create every time, then I am freeing it on form close.  Boundschecker is no longer reporting leaks there.  BUT I appreciate your all replies.

Thanks.
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 12706097
mimran, Are you adding OBJECTS to the stringlist?


Rewrite ReadSpec like this:

procedure  ReadSpec(var Lines: TStringList);
begin
  // Modify Lines...
end;
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 12706755
If he tries it, yes. I think he is trying to modify the original stringlist and all he has to do is
make it a var parameter in the ReadSpec procedure.

You are a Delphi Expert, no? Do you see it as a sloution?
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 12707095
I know I have disparaged you in the past for your selection of solutions and I'm sorry.

I was under the impression that the cleanup moderators had to have a little more knowledge
about the subject they were cleaning up. This way it would be much easier to determine
which solution best fits the question. I do not agree that someone should be a cleanup
volunteer if he knows little or nothing about the subject.

What areas of Delphi are you most familiar with? StringLists is a basic subject that ALL
Delphi developers should be aware of.
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 12708412
If you ever need help figuring out which one to accept, contact me via email at
mr_delphi_developer at yahoo dot com.

I'll be sure to give you a helping hand. I have submitted to anniemod but don't know what else to do.
0
 
LVL 10

Expert Comment

by:János Szabó
ID: 12708469
thanks, registered
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 12708479
If the OP is adding objects to the stringlist, he will need to free them explicitly as well. I can not tell from
his code if that is, indeed, what he is doing so I can not say for sure that what I posted is the correct solution.

Personally, I would have done it like this:

procedure ReadSpec(var ALines: TStringList);
begin
  // Modify ALines here.
  . . .
  Result := ALines;
end;

procedure AddToBatch;
var
  LineInfo: TStringList;
begin
  LineInfo := TStringList.Create;
  try
    //...do something
    ReadSpec(LineInfo);
    if LineInfo.Count = 0 then
    begin
      MessageDlg('No valid lines were found for order: '+OrderNo, mtInformation, [mbOK], 0);
     .....
  except
    ShowMessage('could not add line');
  end;
  {
    If you are adding OBJECTS to the LineInfo StringList in ReadSpec, then you must free
    them explicitly like this:
  for i := LineInfo.Count-1 downto 0 so
  begin
    // Cast this TObject to the type of object you are adding
    TObject(LineInfo.Objects[i]).Free;
  end;
  }
  // THEN you can free the LineInfo StringList
  LineInfo.Free;    
end;
0
 

Author Comment

by:mimran
ID: 12708890
Sorry I have not been in touch here.  This is one year old question I had asked.  I have solved already because I had needed an instant answer.  No body answered for months  but suddenly all of you have been posting your replies for last few days for this one year old question.  I appreciate your all time and efforts providing solutions.  But this issue should be closed.

Thanks
0
 
LVL 26

Accepted Solution

by:
EddieShipman earned 50 total points
ID: 12710245
mimran, that is why it is imperitive that you close old questions.
I replied to your question when looking for old quaetions that had
no answers.

So because you didn't close this question months ago, you wasted
both my and kacor's time.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Magic Software info 18 131
Delphi 2 60
How to make Sign in, using Clientdataset? 1 19
MS Access from Delphi 31 32
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question