I have a procedure that takes a dynamic array TData = TArray<Byte>
as a parameter.
procedure DoStuff(const Input: TData);
begin
// do nothing
end;
And a function that returns a dynamic array.
function SomeData: TData;
begin
Result := [1, 2];
end;
When I use the procedure in the example below, DoStuff gets the following data (1, 2, 3, 1, 3) but I get an EInvalidPointer exception after DoStuff completes.
procedure TForm1.Button1Click(Sender: TObject);
begin
DoStuff([1, 2, 3] + SomeData);
end;
Calling DoStuff([1, 2] + SomeData);
does not result in an error, it seems to get touchy when the array is greater than 4 items. If I use a temp variable to hold the array, DoStuff still gets (1, 2, 3, 1, 2) but there is no error.
procedure TForm1.Button2Click(Sender: TObject);
var
Temp: TData;
begin
Temp := [1, 2, 3] + SomeData;
DoStuff(Temp);
end;
It looks like pointer exception is related to how one of the dynamic arrays are freed when they fall out of scope.
Should I not be using dynamic arrays in this way? When working, this solved my current problem very cleanly.
I also have tried using array of Byte;
instead of TArray<Byte>;
but had the same result.
Full test unit:
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TData = TArray<Byte>;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure DoStuff(const Input: TData);
function SomeData: TData;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
DoStuff([1, 2, 3] + SomeData);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Temp: TData;
begin
Temp := [1, 2, 3] + SomeData;
DoStuff(Temp);
end;
procedure DoStuff(const Input: TData);
begin
// do nothing
end;
function SomeData: TData;
begin
Result := [1, 2];
end;
end.
Your code has no defects and any errors can only be due to compiler / RTL bugs.
Support for dynamic array literals and the dynamic array +
operator was somewhat patchy when first released. These features were added in XE7 and I believe that most of the bugs were ironed out by XE8.
My guess would be that you are using XE7, or perhaps a layer version which still contains a more obscure bug than the many obvious ones from XE7.
Your options would seem to be:
+
operator with dynamic arrays and / or dynamic array literals.I still use XE7 and workaround the issues with my own generic concatenation function. An example of how to do this can be found here: https://stackoverflow.com/a/15924484/505088
Such workaround help you avoid issues with the +
operator, but not if the issue is with handling array literals. If your problem is with array literals then you may end up needing to use TData.Create(1, 2, 3)
in place of [1, 2, 3]
.
If the defect is present in later versions then please submit a bug report to Embarcadero's Quality Portal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With