Monday, January 2, 2006

Why do I get AVs when accessing a TStrings' Objects property?

Typically, this is because a corresponding string has not been assigned.

TStringLists use what is called sparse memory management. This means that memory (including the memory for the object's pointer) is assigned to each element only when something is placed in the string. Therefore, when an object is referenced without the string, no memory is allocated but it is trying to be accessed anyway, hence the AV.

There are a couple solutions: 1) use the AddObject method, 2) assign a value to the corresponding string first.

Note: Objects stored in TStrings descendants do not get freed when the TStrings object is destroyed. The lifetime of anything you place in here must be explicitly maintained.
procedure example1;
begin
with TStringList.Create do
try
Objects[0] := TObject.Create; { This will AV }
finally
Objects[0].Free;
Free;
end;
end;

procedure example2;
begin
with TStringList.Create do
try
AddObject('This is one good way.', TObject.Create);
Add('This is another good way.');
Objects[1] := TObject.Create;
finally
Objects[0].Free;
Objects[1].Free;
Free;
end;
end;

No comments: