MarkShark 27 Posted February 11, 2023 I was writing a simple record helper for TBytes and realized that some of my routines call SetLength. I'm wondering if this is a problem since the array could/will be reallocated in memory. Simple example: TTestBytesHelper = record helper for TBytes private function GetLength: Integer; inline; public function ReadFromStream(AStream: TStream; ACount: Integer): Integer; property Length: Integer read GetLength; end; { TTestBytesHelper } function TTestBytesHelper.GetLength: Integer; begin Result := System.Length(Self); end; function TTestBytesHelper.ReadFromStream(AStream: TStream; ACount: Integer): Integer; begin // Wondering about this SetLength call! System.SetLength(Self, ACount); Result := AStream.Read(Self, ACount); end; In my testing the ReadFromStream function does seem to work fine. I'm just wondering if calling SetLength on Self while in a record helper is ok to do. Thanks for any insight! Share this post Link to post
PeterBelow 238 Posted February 12, 2023 17 hours ago, MarkShark said: I was writing a simple record helper for TBytes and realized that some of my routines call SetLength. I'm wondering if this is a problem since the array could/will be reallocated in memory. Simple example: TTestBytesHelper = record helper for TBytes private function GetLength: Integer; inline; public function ReadFromStream(AStream: TStream; ACount: Integer): Integer; property Length: Integer read GetLength; end; { TTestBytesHelper } function TTestBytesHelper.GetLength: Integer; begin Result := System.Length(Self); end; function TTestBytesHelper.ReadFromStream(AStream: TStream; ACount: Integer): Integer; begin // Wondering about this SetLength call! System.SetLength(Self, ACount); Result := AStream.Read(Self, ACount); end; In my testing the ReadFromStream function does seem to work fine. I'm just wondering if calling SetLength on Self while in a record helper is ok to do. Thanks for any insight! It's OK, a record or helper is just way to add methods for a type, they always work on the instance of the type you call the added method on. 2 Share this post Link to post
programmerdelphi2k 237 Posted February 12, 2023 (edited) unit Unit2; interface uses System.SysUtils, System.Classes; type TMyHelpToTBytes = record helper for TBytes private function MyGetLen: integer; public property MyLen: integer read MyGetLen; function MyGetBytes(const AStream: TStream; const AStart: integer = 0; ACount: integer = 32): TBytes; function MyBytesAsString: string; end; implementation { TMyHelpToTBytes } function TMyHelpToTBytes.MyGetLen: integer; begin result := Length(Self); end; function TMyHelpToTBytes.MyGetBytes(const AStream: TStream; const AStart: integer = 0; ACount: integer = 32): TBytes; begin result := []; // if (AStream = nil) or {(AStart < 0 ) or} (ACount < 1) then exit; // // maybe some protection here to avoid "AV"...? if ((AStart + ACount) > AStream.Size) then ACount := AStream.Size - AStart; // if ACount > 0 then begin Setlength(result, ACount); // AStream.Position := AStart; AStream.Read(result, ACount); end; end; function TMyHelpToTBytes.MyBytesAsString: string; begin result := ''; // for var B in Self do result := result + ',(' + B.ToString + ')'; // result := result.Remove(0, 1); end; end. uses Unit2; procedure TForm1.Button1Click(Sender: TObject); var MyBytes : TBytes; MyStream: TMemoryStream; begin Memo1.Text := 'MyBytes Len = ' + MyBytes.MyLen.ToString + ', time: ' + TimeToStr(now); // MyStream := TMemoryStream.Create; try MyStream.LoadFromFile('..\..\Unit1.pas'); // MyBytes := MyBytes.MyGetBytes(MyStream, random(100), random(1000)); // Memo1.Lines.Add('MyBytes Len = ' + MyBytes.MyLen.ToString); Memo1.Lines.Add(MyBytes.MyBytesAsString); // MyBytes := MyBytes.MyGetBytes(MyStream, random(100), random(500)); // Memo1.Lines.Add('MyBytes Len = ' + MyBytes.MyLen.ToString); Memo1.Lines.Add(MyBytes.MyBytesAsString); // MyBytes := MyBytes.MyGetBytes(MyStream, random(100), random(1500)); // Memo1.Lines.Add('MyBytes Len = ' + MyBytes.MyLen.ToString); Memo1.Lines.Add(MyBytes.MyBytesAsString); finally MyStream.Free; end; end; initialization ReportMemoryLeaksOnShutdown := true; end. Edited February 13, 2023 by programmerdelphi2k 1 Share this post Link to post