Advice on "Invalid Pointer Operation" when using complex records
- by Xaz
Env: Delphi 2007
<JustificationI tend to use complex records quite frequently as they offer almost all of the advantages of classes but with much simpler handling.</Justification
Anyhoo, one particularly complex record I have just implemented is trashing memory (later leading to an "Invalid Pointer Operation" error).
This is an example of the memory trashing code:
sSignature := gProfiles.Profile[_stPrimary].Signature.Formatted(True);
On the second time i call it i get "Invalid Pointer Operation"
It works OK if i call it like this:
  AProfile    := gProfiles.Profile[_stPrimary];
  ASignature  := AProfile.Signature;
  sSignature  := ASignature.Formatted(True);
Background Code:
  gProfiles: TProfiles;
  TProfiles = Record
  private
    FPrimaryProfileID: Integer;
    FCachedProfile: TProfile;
    ...
  public
    < much code removed >
    property Profile[ProfileType: TProfileType]: TProfile Read GetProfile;
  end;
  function TProfiles.GetProfile(ProfileType: TProfileType): TProfile;
  begin        
    case ProfileType of
      _stPrimary        : Result := ProfileByID(FPrimaryProfileID);
      ...
    end;
  end;
  function TProfiles.ProfileByID(iID: Integer): TProfile;
  begin
    <snip>
    if LoadProfileOfID(iID, FCachedProfile)  then
    begin
      Result := FCachedProfile;
    end
    else
    ...
  end;
  TProfile = Record
  private     
    ...
  public
    ...
    Signature: TSignature;
    ...
  end;
  TSignature = Record
  private               
  public
    PlainTextFormat : string;
    HTMLFormat      : string;
    // The text to insert into a message when using this profile
    function Formatted(bHTML: boolean): string;
  end;
  function TSignature.Formatted(bHTML: boolean): string;
  begin
    if bHTML then
      result := HTMLFormat
    else
      result := PlainTextFormat;
    < SNIP MUCH CODE >
  end;
OK, so I have a record within a record within a record, which is approaching Inception level confusion and I'm the first to admit is not really a good model.  Clearly i am going to have to restructure it.  What I would like from you gurus is a better understanding of why it is trashing the memory (something to do with the string object that is created then freed...) so that i can avoid making these kinds of errors in future.
Thanks