C#プログラム

【C#】メモリの値コピー、ポインタ、1次元、2次元、3次元配列間

C#でメモリのポインタ(IntPtr)と一次元配列間の値のコピーにはMarshal.Copyメソッド(名前空間:System.Runtime.InteropServices)を用います。

Marshal.Copyにはポインタから一次元配列へのコピー および 一次元配列からポインタへのコピーが用意されています。

一次元配列の型は、Single[], IntPtr[], Byte[], Single[], Int64[] , Int32[] , Int32[] , Int16[] , Double[]が指定可能です。

Mershal.Copyが可能なのは、あくまでも一次元配列が対象となります。

 

多次元配列(1次元、2次元、3次元…)と多次元配列間の値のコピーにはBuffer.BlockCopyメソッド(名前空間:System)を用います。

このメソッドでは、異なる次元の配列間、異なる型の配列間でメモリをコピーしてくれます。

異なる型の場合は、値のコピーではありません。

どちらかというと、C言語のCopyMemoryの挙動に似ています。

 

サンプルプログラム

// 一次元配列、二次元配列、三次元配列を確保(全て24バイト)
var arr1D = new byte[24] ;
var arr2D = new byte[6, 4];
var arr3D = new byte[2, 3, 4];
var arrUS = new ushort[12];

// メモリの確保(24バイト)
IntPtr ptr = Marshal.AllocHGlobal(24);

// 値の代入
for (byte i = 0; i < 24; i++)
{
    Marshal.WriteByte(ptr, i, i);
}
// ポインタから一次元配列へコピー
Marshal.Copy(ptr, arr1D, 0, arr1D.Length);

// 一次元配列から二次元配列へコピー
Buffer.BlockCopy(arr1D, 0, arr2D, 0, arr1D.Length * sizeof(byte));
// 二次元配列から三次元次元配列へコピー
Buffer.BlockCopy(arr2D, 0, arr3D, 0, arr2D.Length * sizeof(byte));
// byte配列からushort配列へコピー
Buffer.BlockCopy(arr1D, 0, arrUS, 0, arr1D.Length * sizeof(byte));

// メモリの解放
Marshal.FreeHGlobal(ptr);

 

実行後の配列の値は以下のようになります。

C# メモリの値コピー C# メモリの値コピー C# メモリの値コピー C# メモリの値コピー

 

ushort配列の結果が少しわかりづらいですが、byte配列の2バイト分が1つのushortの値として格納されます。

 

C# メモリの値コピー

 

参考ページ

【C#】配列の中身をメモリで確認する方法
C言語の時は、ポインタの中身をメモリで参照する事が多かったのですが、C#をメインで触るようになってからは、メモリの中身を参照することは無くなってしまい、いざ、やってみようとすると、やり方がわかりづらかったので記事にしました。 まず、Visu...

 

コメント

タイトルとURLをコピーしました