Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

TStringList Freeing

Posted on 2003-11-07
23
Medium Priority
?
358 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
16 Comments
 
LVL 26

Expert Comment

by:Eddie Shipman
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

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:Eddie Shipman
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:Eddie Shipman
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:Eddie Shipman
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:Eddie Shipman
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:Eddie Shipman
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:kacor
ID: 12708469
thanks, registered
0
 
LVL 26

Expert Comment

by:Eddie Shipman
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:
Eddie Shipman earned 150 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…
Suggested Courses

580 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