簡素化したコードを作ってみたのですが下記コードでもエラーが出ます。
古いバージョンでは可能だったように思ったのですがうまくいきません。access violationです。
良い方法はないでしょうか。
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes;
var
ms: TMemoryStream;
i: integer;
a: ^TArray<integer>;
begin
try
{ TODO -oUser -cConsole メイン : ここにコードを記述してください }
ms := TMemoryStream.Create;
i := 7;
ms.WriteData(i);
i := 3;
ms.WriteData(i);
a := ms.Memory;
Writeln('start');
for i := 0 to ms.Size div SizeOf(Integer) do
Writeln(a^[i]);
Readln;
ms.Free;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
TArray<T> は動的配列の型です.
SetLength で領域 (要素数) の確保が必要です.
要素が 2 つの時は 0, 1 までです.
for i := 0 to ms.Size div SizeOf(Integer) do
↓
for i := 0 to ms.Size div SizeOf(Integer) - 1 do
> a := ms.Memory;
動的配列に対してこのような操作はできません.
TMemoryStream のデータを動的配列に読み込ませたいのあれば,
TMemoryStream.Read メソッドを使用します.
// a の変数の型は TArray<Integer> (^ はなし)
SetLength(a,2);
ms.Position := 0;
ms.Read(a[0], SizeOf(Integer) * Length(a));
よくわかりました。ありがとうございました。
>> a := ms.Memory;
やるならば,
Pointer(a) := ms.Memory;
ですね.
ただし,これは TMemoryStream のデータを配列に読み込むのではなく,
TMemoryStream のデータのアドレスと配列のデータのアドレスを同じにする操作です.
ポインタに関する操作ですから,いろいろ注意が必要です.
Pointer(a) := ms.Memory;
ms.Position := Sizeof(Integer);
i := 12345;
ms.WriteData(i);
// a[1] の値は 12345 になる
a[0] := 5005;
ms.Position := 0;
ms.ReadData(i);
// i の値は 5005 になる
ツイート | ![]() |