Можно ли использовать возврат ссылки на преобразованное значение указателя в C#? - PullRequest
2 голосов
/ 14 февраля 2020

Можно ли использовать ссылочный возврат значения преобразованного указателя?

Я прочитал этот вопрос. Как возврат по ссылке реализован в C#?

Можно ли использовать приведенный ниже код для решения проблемы перемещения памяти сборщиком мусора. (Helper.GetReference () & Helper.GetPointer ())

class Program
{
    static unsafe void Main(string[] args)
    {
        byte[] bytes = new byte[1024];

        ref SomeStruct reference = ref Helper.GetReference<SomeStruct>(bytes);
        reference.field1 = 1;
        reference.field2 = 2;

        SomeStruct* pointer = Helper.GetPointer<SomeStruct>(bytes);
        pointer->field1 = 3;
        pointer->field2 = 4;
    }
}

public static class Helper
{
    // Can I use this?
    public static unsafe ref T GetReference<T>(byte[] bytes) where T : unmanaged
    {
        fixed (byte* p1 = bytes)
        {
            T* p2 = (T*)p1;
            return ref *p2;
        }
    }

    // Shouldn't I use it?
    public static unsafe T* GetPointer<T>(byte[] bytes) where T : unmanaged
    {
        fixed (byte* p1 = bytes)
        {
            return (T*)p1;
        }
    }
}

public struct SomeStruct
{
    public int field1;
    public int field2;
}

1 Ответ

2 голосов
/ 14 февраля 2020

Насколько я знаю, оба эти метода небезопасны ... Да, он компилируется, однако, потому что вы использовали unsafe в ваших Helper методах и ссылались на одну и ту же память, ваш safety- net было взорвано.

Вы указывает на часть памяти (управляемый объект), которая может быть перемещена с помощью Garbage Collector (он же ваш массив), потенциально оставляющий вам висячий указатель

. Вам необходимо исправить (fixed) массива в вашем Main метод обеспечения безопасности (как мне кажется) или ваша структура

Например

fixed (byte* p = bytes) // even though p isn't being used
{
   SomeStruct* pointer = Helper.GetPointer<SomeStruct>(bytes);
   pointer->field1 = 3;
   pointer->field2 = 4;
}
...