In C, if I have the following struct Data:
struct __attribute__((__packed__)) Data
{
double x;
int y;
};
And then create an array named val of this struct:
Data val[3];
All values stored in val (i.e. val[0].x, val[0].y, val[1].x, val[1].y, val[2].x and val[2].y are contiguous in memory.
Now, when having the following struct in C#:
[StructLayout(LayoutKind.Sequential, Pack=0)]
struct Data
{
public double x;
public int y;
}
And then create an array named val of this struct:
Data val[3];
I would expect that all values stored in val are contiguous in memory, which they are not (based on the tests that I have conducted). In details, val[0].x and val[0].y are both contiguous, but they are not contiguous with val[1] (which, in turn, is not contiguous with val[2]).
My question is: in C#, how can I create a variable (that is an array) of a certain struct that all its elements and members are contiguous in memory?
>Solution :
Just to try it, I made a very simple project: using Pack=1 seems to pack perfectly fine.
Reproducing code (on a console app):
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Data
{
public double x;
public int y;
}
class Program {
static void Main()
{
Data[] val = new Data[3] {
new Data { x = 0, y = 0 },
new Data { x = 1, y = 1 },
new Data { x = 2, y = 2 },
};
for(var i = 0; i < 3; i++)
{
Console.WriteLine("data[" + i + "].x = " + BitConverter.ToString(BitConverter.GetBytes(val[i].x)));
Console.WriteLine("data[" + i + "].y = " + BitConverter.ToString(BitConverter.GetBytes(val[i].y)));
}
unsafe {
fixed (Data *p = &val[0])
{
byte *c = (byte *)p;
for(var j = 0; j < 3; j++)
{
for(var i = 0; i < Marshal.SizeOf<double>(); i++, c++)
{
if(i!=0) Console.Write("-");
Console.Write("{0:X2}", *c);
}
Console.WriteLine();
for(var i = 0; i < Marshal.SizeOf<int>(); i++, c++)
{
if(i!=0) Console.Write("-");
Console.Write("{0:X2}", *c);
}
Console.WriteLine();
}
}
}
}
}
Output:
data[0].x = 00-00-00-00-00-00-00-00
data[0].y = 00-00-00-00
data[1].x = 00-00-00-00-00-00-F0-3F
data[1].y = 01-00-00-00
data[2].x = 00-00-00-00-00-00-00-40
data[2].y = 02-00-00-00
00-00-00-00-00-00-00-00
00-00-00-00
00-00-00-00-00-00-F0-3F
01-00-00-00
00-00-00-00-00-00-00-40
02-00-00-00
Which looks perfectly continuous to me, unless I’m missing something