As a general rule, CPU's like to have variables aligned in memory at location that is an even multiple of their size, so a 4 byte int should be on a memory address that is divisible by 4,
and an 8 byte long should be at an address divisible by 8.
The C# (and C++) language designers know this and they will insert padding in structures to provide the necessary alignement. So the actual layout of your structure looks like this
public struct NetPoint {
public float lat; // 4 bytes offset 0
public float lon; // 4 bytes offset 4
public int alt; // 4 bytes offset 8
int to_preserve_alignment; // 4 bytes offset 12
public long time; // 8 bytes offset 16
}
You can fix this by making the long the first value, as a rule, if you always put the largest values at the beginning of your structures, you won't have any padding inserted to preserve alignment of members.
You can also fix it by adding
[StructLayout(LayoutKind.Sequential, Pack = 4)]
before the structure declaration, but that will result in mis-aligned long time
which hurts performance, on some CPUs it hurts performance quite a lot. (The ALPHA AxP would fault on misaligned members, for instance). x86 CPUs have only a minor performance penalty, but there is a danger of future CPUs having a major performance penalty, so it's best to design your structs to align properly (rather than packing them) if you can.