TStringList Freeing

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.
mimranAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Eddie ShipmanAll-around developerCommented:
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
meceCommented:
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
mimranAuthor Commented:
Hi,
I could not reply because of week end.  Thanks I will try these code right now..
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

mimranAuthor Commented:
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
meceCommented:
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
tuzaiCommented:
I think the 《Mastering the delphi7》has discussed this question more detail.
0
Eddie ShipmanAll-around developerCommented:
You do not have to free the stringlist created in the function ReadSpec.
0
mimranAuthor Commented:
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
Eddie ShipmanAll-around developerCommented:
mimran, Are you adding OBJECTS to the stringlist?


Rewrite ReadSpec like this:

procedure  ReadSpec(var Lines: TStringList);
begin
  // Modify Lines...
end;
0
Eddie ShipmanAll-around developerCommented:
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
Eddie ShipmanAll-around developerCommented:
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
Eddie ShipmanAll-around developerCommented:
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
kacorretiredCommented:
thanks, registered
0
Eddie ShipmanAll-around developerCommented:
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
mimranAuthor Commented:
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
Eddie ShipmanAll-around developerCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.