[Unity.Physics] Confused by SphereCollider.Create and lifetime

[EDIT]: Progress made, question revised in reply

TLDR: I’m not sure how taking ref to local var is sound

Hi, I was reading the Unity.Physics manual again and this line caught my eye:

BlobAssetReference<Collider> sphereCollider = SphereCollider.Create(sphereGeometry, filter);

I was interested, as no allocator is specified, but I knew that BlobAssetReference holds a pointer to something.

I looked at the SphereCollider.Create method and saw this (I’ve added the comments):

public static unsafe BlobAssetReference<Collider> Create(SphereGeometry geometry, CollisionFilter filter, Material material)
{
  var collider = default(SphereCollider); // line 1
  collider.Init(geometry, filter, material); // line 2
  return BlobAssetReference<Collider>.Create(&collider, sizeof(SphereCollider)); // line 3
}

Line 1 & 2 make sense to me, we make a struct (on the stack presumably), and Init sets up its local members.
On line 3, we take a pointer to the struct, which is also fine, make the BlobAssetReference, but then we return.

On return I assume we pop the stack, which I’ve assumed is storing the collider. We then would have a BlobAssetReference into the remains of that stack-frame, which is unsound.

I’ve looked for parallels in c# itself, and ‘ref returns’ are one example. However, they explicitly forbid returning refs to local variables.

Please can someone point me to the parts of the spec or runtime info that explain how this is valid.

Thanks!

AH, my bad, BlobAssetReference<T>.Create Allocates persistent storage and then copies the data from the src pointer into it

public static BlobAssetReference<T> Create(void* ptr, int length)
{
    byte* buffer =
   (byte*) UnsafeUtility.Malloc(sizeof(BlobAssetHeader) + length, 16, Allocator.Persistent);
    UnsafeUtility.MemCpy(buffer + sizeof(BlobAssetHeader), ptr, length);
... ETC ...

However this then begs another question.

In the manual here: Collision queries | Unity Physics | 0.3.2-preview we see that the SphereCollider is created but never disposed. Is that a mistake?

Yes, this particular example is missing the dispose. You can turn on the leak detection in the editor and make sure you are disposing all the memory needed.

1 Like

Thanks @petarmHavok , it all makes a bit more sense now :slight_smile:

1 Like