Does TJpegImage need to be freed?

Does TJpegImage need to be freed?

Post by Mike Warre » Thu, 23 Jun 2005 08:54:23


Hi,

I have a strange situation occurring and want to try to understand it.

First, some background. These are the relevant areas of my code:

TMediaListItem = record
Artist: string;
Title: string;
FileType: string;
Flags: string;
FileName: string;
Credits: Integer;
Jpeg: TJpegImage;
end;

procedure TMediaList.Add(AArtist, ATitle, AFileType, AFlags,
AFileName: string; ACredits: Integer);
begin
SetLength(fItems, Length(fItems) + 1);
fItems[High(fItems)].Artist := AArtist;
fItems[High(fItems)].Title := ATitle;
fItems[High(fItems)].FileType := AFileType;
fItems[High(fItems)].Flags := AFlags;
fItems[High(fItems)].FileName := AFileName;
fItems[High(fItems)].Credits := ACredits;
fItems[High(fItems)].Jpeg := TJpegImage.Create;
end;

procedure TMediaList.Delete(AIndex: Integer);
var
I: Integer;
begin
CheckIndex(AIndex);
for I := AIndex to Length(fItems) -2 do
fItems[I] := fItems[I + 1];
fItems[High(fItems)].Jpeg.Free; // This is the problem line
SetLength(fItems, Length(fItems) -1);
end;

To add an item to the MediaList I call the Add() method and then later
assign a jpeg to it:

MediaList.Items[I].Jpeg.Assign(FileTag.Track.Jpeg);

When I want to delete a MediaList.Item I get an AV at 0 on the
fItems[High(fItems)].Jpeg.Free; line.

I have done similar things in the past (not with TJpegImage).

From what I can understand of the D7 help, TJpegImage is reference
counted so I am guessing that has something to do with my problem.

If I remove the offending line I would imagine the potential for a memory
leak.

Does anyone have an idea of what I should do?

-Mike
 
 
 

Does TJpegImage need to be freed?

Post by Lord Cr » Thu, 23 Jun 2005 10:54:08

On Wed, 22 Jun 2005 09:54:23 +1000, "Mike Warren"



fItems[high(fItems)] now contains the same item as
fItems[high(fItems)-1]. When you .Free it, you obviously free the same
JPEG object as in fItems[high(fItems)-1], causing your trouble.

What you should do, is to FIRST free / deallocate the memory for the
object you want to remove, THEN shift the items in the array:

procedure TMediaList.Delete(AIndex: Integer);
var
I: Integer;
begin
CheckIndex(AIndex);
fItems[AIndex].Jpeg.Free; // free item's jpeg instance
for I := AIndex to Length(fItems) -2 do
fItems[I] := fItems[I + 1];
SetLength(fItems, Length(fItems) -1);
end;

- Asbjn

 
 
 

Does TJpegImage need to be freed?

Post by Mike Warre » Thu, 23 Jun 2005 10:57:32

>> for I := AIndex to Length(fItems) -2 do


Of course. How silly of me. Thanks

-Mike
 
 
 

Does TJpegImage need to be freed?

Post by Lord Cr » Thu, 23 Jun 2005 13:57:58

On Wed, 22 Jun 2005 11:57:32 +1000, "Mike Warren"



If it makes you feel better, I have at least 2-3 of those moments a
day ;)

- Asbjn