Непонятное поведение фиксированного указателя вне фиксированного оператора.

StackOverflow https://stackoverflow.com/questions/862936

  •  21-08-2019
  •  | 
  •  

Вопрос

Может кто-нибудь объяснить мне, почему приведенный ниже код C # не дает сбоя?Почему Visual Studio на самом деле позволяет его скомпилировать?Насколько я понимаю, я получаю фиксированный указатель, но он фиксируется только внутри оператора «fixed».Когда указатель возвращается из функции Foo, можно собрать массив ar.Затем я заставляю GC сделать это, но последовательная запись в память (которая теперь освобождена) не вызывает никаких ошибок.

class Program
{
    static unsafe byte* Foo()
    {
        byte[] ar = new byte[100];
        fixed (byte* ptr = ar)
        {
            return ptr;
        }
    }

    static unsafe void Main(string[] args)
    {
        byte* ptr = Foo();
        GC.Collect();
        for (int t = 0;;++t) ptr[t%100] = 0;
    }
}
Это было полезно?

Решение

Эрик прав, но ответ, который вы, вероятно, захотите услышать, заключается в том, что «иногда полезно сохранять адрес за пределами фиксированного оператора».

Может быть, память от этого указателя уже зафиксирована другим фиксированным оператором где-то еще, и имеет смысл ее вернуть?Компилятор не пытается вас угадать и выдать шумные предупреждения.

Тем не менее, я надеюсь, что CodeAnalysis или другие продвинутые инструменты вмешаются здесь, где компилятор позволяет вам отрезать себе ногу.

Другие советы

Тот факт, что память освобождена, не означает, что запись в нее приведет к какой-либо ошибке.Когда сборщик мусора освобождает память, он просто помечает ее как свободную на своей внутренней карте памяти — он не возвращает ее сразу ОС, поэтому она по-прежнему остается подходящей памятью для использования вашим процессом.

Конечно, использование указателя за пределами фиксированного блока является ошибкой. очень плохая идея - не делай этого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top