Array element reference being set to partially incorrect memory address and data.

MichaelS-8741 0 Reputation points
2023-11-06T19:11:52.4733333+00:00

I am at the point in the custom ECS I'm making where I am trying to retrieve components I've stored. The issue is when I try to access the array element as a reference it ends up having a memory address that is half right; and the data I return ends up being nothing I've set (should be 150, ends up returning random garbage data).

Correct : 0x000000123456789A

What i get : 0xFFFFFFFF3456789A or 0x000000003456789A (always starts with either eight 0's or F's)

When I debug the reference to the array itself visual studio shows that the memory address is pointing to my original array and the data I set is all there. I am not new to C# or pointers; but I am new to the 'ref' keyword, unsafe code, and any of the nuances it may have.

The actual code for trying to return said component reference is :

public struct Block
{    
	private Array[] components;    
	
	unsafe public readonly ref T Get<T>(int entity)    
	{        
		ref ComponentType cType = ref ComponentType.GetInfo<T>();    
    
		ref Array array = ref components[cType.ID];    
		T[] cmp = Unsafe.As<T[]>(array); 

		return ref cmp[entityID];   
 	}
}

I've tried accessing the data in as many ways that I can think of such as using an Unsafe.As cast, raw pointers in a fixed statement, and some of CommunityToolkit.HighPerformance array extensions; all of which resulted in the same memory address issues as I had above. My current best guess is the references to the arrays are incorrect in a way I don't quite understand, and my index to the element isn't going where I think it's going memory-wise.

To clarify the issue I am having, what is happening is I'm not getting the proper data when I try to access the individual elements from my arrays; which show they have the proper data set in them (array says it is storing [ 150, 21 ]) but when trying to access either I'm getting back a garbage number). In debugging the memory I found that what seems to be the issue is the address it is accessing, ref cmp[index] , is half similar to the actual address of ref cmp[index] which would explain why I'm not getting the right data from Get (address of cmp[index] that I want to return is 0x00000123456789AB the reference address my Get function returns ends up being 0x00000000456789AB or 0xFFFFFFFF456789AB and having mangled data as it is not pointing to the right address).

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,649 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,650 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 61,731 Reputation points
    2023-11-06T22:34:57.7466667+00:00

    not sure why you use all the ref variables and unsafe. Array[] is a an array of arrays. you just need to index and cast.

    ref cmp[entityID] will returns a ref variable for array entry of the index.

        public readonly ref T Get<T>(int entity)    
    	{        
    		var cType = ComponentType.GetInfo<T>();    
     		var cmp = components[cType.ID] as T[]; // not sure why ID is the array index
    
    		return ref cmp[entity];   
     	}
    
    
        ...
        ref MyType v = foo.Get<MyType>(2);
        v = new MyType {};  // update the internal array
    
    

    the array entry is either a value or object reference.

    if you wanted the actual address, then you use unsafe and &

    unsafe public readonly T* Get<T>(int entity)
    {
        ...
        return &cmp[entityID];
    }
    

    this generally won't really work as the cmp is movable and needs to be fixed.

    see unsafe code:

    https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/unsafe-code#234-fixed-and-moveable-variables

    you don't really explain what your issue is.