The snippet below reproduces the error. The short of it is if I create a struct using a custom constructor and add it to a list then the padding in that struct is garbage. This is NOT the case if I create a default struct first and set the values or just turn off Burst. This is causing some issues in our project because we assume that memory is zero (and it is without burst!).
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using UnityEngine;
public class TestBurstStructConstructor : MonoBehaviour
{
public struct TestStruct
{
public int intValue;
public byte byteValue;
public TestStruct(int intValue, byte byteValue)
{
this.intValue = intValue;
this.byteValue = byteValue;
}
}
// If we don't use burst then there isn't any problems
[BurstCompile(CompileSynchronously = true)]
private struct AddJob : IJob
{
public NativeList<TestStruct> list;
public void Execute()
{
// The padding after the byte is 'random'
list.Add(new TestStruct(0, 0));
// Below works correctly even with burst
//TestStruct ts = default;
//ts.intValue = 0;
//ts.byteValue = 0;
//list.Add(default);
}
}
private void Update()
{
NativeList<TestStruct> list = new NativeList<TestStruct>(Allocator.TempJob);
AddJob job = default;
job.list = list;
job.Schedule().Complete();
LogMemory(list);
list.Dispose();
}
private unsafe void LogMemory(NativeList<TestStruct> list)
{
void* ptr = list.GetUnsafeReadOnlyPtr();
int sizeInBytes = list.Length * UnsafeUtility.SizeOf<TestStruct>();
string msg = "";
for (int i = 0; i < sizeInBytes; i++)
{
if (i != 0 && i % 8 == 0)
{
msg += "\n";
}
if (i % 8 != 0 && i % 4 == 0)
{
msg += " ";
}
byte b = *(((byte*) ptr) + i);
msg += b.ToString("X2") + " ";
}
Debug.Log(msg);
}
}
Running the script above my expectation is 00 00 00 00 00 00 00 00 printed repeatedly. This is the case if I don’t use burst or if I set with default. But using the custom constructor for the struct results in garbage (potentially) in the final three bytes.
Unity: 2019.3.0b5
Burst: preview.6 - 1.2.0
As an aside is there a good tool to get a look at a memory location for Unity projects? Rider doesn’t seem to do it and Visual Studio tells me ‘unable to evaluate expression’. Seems like a tool that can is gonna become much more important for Unity development (at least if developing low level).