Исправлено заявление в C # - PullRequest
       61

Исправлено заявление в C #

12 голосов
/ 30 сентября 2008

У нас есть код, подобный следующему в одном из наших проектов. Может кто-нибудь объяснить (простым английским языком), почему здесь требуется фиксированное утверждение?

class TestClass
{
    int iMyVariable;
    static void Main()
    {
        TestClass oTestClass = new TestClass();
        unsafe
        {
            fixed (int* p = &oTestClasst.iMyVariable)
            {
                *p = 9;
            }
        }
    }
}

Ответы [ 5 ]

17 голосов
/ 30 сентября 2008

Исправляет указатель в памяти. Языки со сборкой мусора могут свободно перемещать объекты по памяти для повышения эффективности. Это все прозрачно для программиста, потому что они на самом деле не используют указатели в «нормальном» коде CLR. Однако, если вам нужны указатели, вам нужно исправить их в памяти, если вы хотите работать с ними.

9 голосов
/ 30 сентября 2008

Оператор fixed будет «закреплять» переменную в памяти, чтобы сборщик мусора не перемещал ее при сборе. Если он переместит переменную, указатель станет бесполезным, и при его использовании вы попытаетесь получить доступ или изменить что-то, что вы не намеревались.

7 голосов
/ 30 сентября 2008

Она нужна вам везде, где вы делаете арифметику с указателями, чтобы сборщик мусора не перемещал ее на вас.

2 голосов
/ 30 сентября 2008

MSDN имеет очень похожий пример. Оператор fixed в основном блокирует сборку мусора. В .Net, если вы используете указатель на область памяти, среда выполнения может в любой момент перераспределить объект в «лучшую» область. Поэтому, если вы хотите получить доступ к памяти напрямую, вам нужно исправить ее на месте.

2 голосов
/ 30 сентября 2008

Поскольку вы работаете в небезопасном режиме (указатель), фиксированная инструкция выделяет определенную область памяти для этой переменной. Если вы не поместили фиксированную инструкцию, сборщик мусора может переместить в память переменную куда угодно, когда захочет.

Надеюсь, что это поможет.

...