Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-03

Newbie problems with memory leak and access violation/AV

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jim

Hi all,

Background: Hobby programmer; Microsoft Access VBA/Visual Basic 6/Visual Basic.Net background.
I'm a FreePascal newbie but have fiddled with it some time ago. Was looking into learning C++ but that seems too curly, so started again. I've decided to write a file scanner program that indexes files and can function as a Unix locate or CD indexer program replacement.

System: Windows Vista x64, (Lazarus and) Free Pascal Compiler version 2.4.1 [2010/03/13] for x86_64.
Had FPC 2.4 on Ubuntu 9.10 x32 as well, but got rid of it as my disk space ran low. Have an OS X machine with Lazarus/FPC (don't remember which version.

Problem: Probably due to my innocence, I seem to leak memory all over the place as attested by fpc -gl -gh.
Also, after fiddling with swallowing exceptions and then deciding to allow them to see what code is broken and fix the code, I get an AV. To try and pinpoint the problem, I've slimmed down the program into a simple program which you can find at:
http://bitbucket.org/jb/flocate/issue/1/access-violation-and-memory-leaks I've included the heaptrc trace as well as my debug output in the comments.

What I'm trying to do: I'm adding details for each file I've found into
a new record. I then try to add a pointer to this record to an entry in
a TFPList. The code seems to bomb on the Res.Add line:
Procedure TFileSearch.AddFileToResult(ThisDir: Ansistring; item:
TSearchRec);
var
   APResultRecord : PResultRecord; // We use this pointer to store our
result.
begin
   //{$IFDEF DEBUG}(stderr, 'Debug: ', DateTimeToStr(Now), ': File
',ThisDir,Item.Name,' is a symlink: ', (Item.Attr And
faSymlink)=faSymLink);{$ENDIF}
   New(APResultRecord); //Create and assign memory to a new
TResultRecord record and store its pointer:
   APResultRecord^.Directory:=ThisDir;
   APResultRecord^.FileName:=Item.Name;
   APResultRecord^.ModifyTime:=FileDateToDateTime(Item.Time);
   APResultRecord^.Size:=Item.Size;
   {$IFDEF CRAZYDEBUG}writeln(stderr, 'Debug: ', DateTimeToStr(Now), ':
going to get hash for:', ThisDir, Item.Name);{$ENDIF}
   APResultRecord^.MD5Hash:=GetMD5Hash(ThisDir + Item.Name);
   {$IFDEF DEBUG}writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': going
to add data to list for:', ThisDir, Item.Name);{$ENDIF}
   try
   Res.Add(APResultRecord); //add the pointer to the TFPList
   except
   {$IFDEF DEBUG}
   //doesn't seem to get called either.... just get av!!
   writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': Adding point to
list went wrong. Info: ', ThisDir, Item.Name);
   writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ',
APResultRecord^.Directory);
   writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ',
APResultRecord^.FileName);
   writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ',
APResultRecord^.ModifyTime);
   writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ',
APResultRecord^.Size);
   writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ',
APResultRecord^.MD5Hash);
   {$ENDIF}
   end;
 end;

Could somebody tell me:
1. what I've done wrong regarding the AV
2. how I can fix the memory leaks
I probably don't grasp some basics on memory management...

Of course, suggestions for improvement are also welcomed; if you want to, you can have a look at the rest of the program or get the latest version on:
http://bitbucket.org/jb/flocate/get/tip.zip

If you need more detail, I'd be happy to (try and ;) give it...

Thanks,
jb

Michael Van Canneyt
to Jim
Jim wrote 23 lines
Hi all, Background: Hobby programmer; Microsoft Access VBA/Visual Basic 6/Visual Basic.Net background. I'm a FreePascal newbie but have fiddled with it some time ago. Was looking into learning C++ but that seems too curly, so started again. I've decided to write a file scanner program that indexes files and can function as a Unix locate or CD indexer program replacement. System: Windows Vista x64, (Lazarus and) Free Pascal Compiler version 2.4.1 [2010/03/13] for x86_64. Had FPC 2.4 on Ubuntu 9.10 x32 as well, but got rid of it as my disk space ran low. Have an OS X machine with Lazarus/FPC (don't remember which version. Problem: Probably due to my innocence, I seem to leak memory all over the place as attested by fpc -gl -gh. Also, after fiddling with swallowing exceptions and then deciding to allow them to see what code is broken and fix the code, I get an AV. To try and pinpoint the problem, I've slimmed down the program into a simple program which you can find at: http://bitbucket.org/jb/flocate/issue/1/access-violation-and-memory-leaks I've included the heaptrc trace as well as my debug output in the comments.
After allocating an object which you will free in the same routine, you
should ALWAYS put a try..finally statement, and free the object in the
finally clause:
   Search := TFileSearch.Create;
   try
     // your code
   finally
     Search.free;
   end;

After that, the error still happens, but at least there is no memory leak.

The error is the following:

    FreeAndNil(Item); //Don't really now if we should do this but it can't hurt. Can it?

It CAN hurt: TSearchRec is a record, you don't need to free it.

Michael.

Show quoted text 63 lines
What I'm trying to do: I'm adding details for each file I've found into a new record. I then try to add a pointer to this record to an entry in a TFPList. The code seems to bomb on the Res.Add line: Procedure TFileSearch.AddFileToResult(ThisDir: Ansistring; item: TSearchRec); var APResultRecord : PResultRecord; // We use this pointer to store our result. begin //{$IFDEF DEBUG}(stderr, 'Debug: ', DateTimeToStr(Now), ': File ',ThisDir,Item.Name,' is a symlink: ', (Item.Attr And faSymlink)=faSymLink);{$ENDIF} New(APResultRecord); //Create and assign memory to a new TResultRecord record and store its pointer: APResultRecord^.Directory:=ThisDir; APResultRecord^.FileName:=Item.Name; APResultRecord^.ModifyTime:=FileDateToDateTime(Item.Time); APResultRecord^.Size:=Item.Size; {$IFDEF CRAZYDEBUG}writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': going to get hash for:', ThisDir, Item.Name);{$ENDIF} APResultRecord^.MD5Hash:=GetMD5Hash(ThisDir + Item.Name); {$IFDEF DEBUG}writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': going to add data to list for:', ThisDir, Item.Name);{$ENDIF} try Res.Add(APResultRecord); //add the pointer to the TFPList except {$IFDEF DEBUG} //doesn't seem to get called either.... just get av!! writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': Adding point to list went wrong. Info: ', ThisDir, Item.Name); writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ', APResultRecord^.Directory); writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ', APResultRecord^.FileName); writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ', APResultRecord^.ModifyTime); writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ', APResultRecord^.Size); writeln(stderr, 'Debug: ', DateTimeToStr(Now), ': ', APResultRecord^.MD5Hash); {$ENDIF} end; end; Could somebody tell me: 1. what I've done wrong regarding the AV 2. how I can fix the memory leaks I probably don't grasp some basics on memory management... Of course, suggestions for improvement are also welcomed; if you want to, you can have a look at the rest of the program or get the latest version on: http://bitbucket.org/jb/flocate/get/tip.zip If you need more detail, I'd be happy to (try and ;) give it... Thanks, jb _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jim
to Michael Van Canneyt
Michael Van Canneyt wrote
After allocating an object which you will free in the same routine, you should ALWAYS put a try..finally statement, and free the object in the finally clause:

++ makes sense.

Show quoted text 9 lines
After that, the error still happens, but at least there is no memory leak. The error is the following: FreeAndNil(Item); //Don't really now if we should do this but it can't hurt. Can it? It CAN hurt: TSearchRec is a record, you don't need to free it.

++Ok, clear.

Michael.

Michael,

Thanks for the quick & clear explanation! I'll give it a go and get back to the list if (when ;) I've got more problems...

jb