Вернуть фиксированный указатель в C # - PullRequest
3 голосов
/ 05 января 2012

Мне было интересно, безопасно ли возвращать фиксированный указатель из одного метода в другой метод - закрепленный объект все еще остается фиксированным?например,

struct TestData
{
    public int value;
}

public class Class1
{
    private TestData data; 

    public unsafe TestData* GetDataPtr()
    {
        fixed (TestData* ptr = &data)
        {
            // IS THIS SAFE?
            return ptr; 
        }
    }
}

public class Class2
{
    public unsafe void Test()
    {
        Class1 x = new Class1();

        TestData* ptr = x.GetDataPtr(); // is this still fixed?
        ptr->value = 2; 
    }
}

Причина, по которой я спрашиваю, заключается в использовании чего-то в этом стиле, я получаю исключения AccessViolation.Но так как я изменил его, например, на установленное значение непосредственно из Class1, я не видел, чтобы проблема возникала.

РЕДАКТИРОВАТЬ: причина, по которой я думал, что это может быть исправлено, заключается в том, что снаружи "TestData * ptr = x.GetDataPtr() «вы пытаетесь поставить fixed (), вы получаете« вы не можете взять адрес уже фиксированного выражения »... Теперь я понимаю, что это говорит о том, что моя переменная "ptr" в "Test ()" уже исправлена ​​..

1 Ответ

11 голосов
/ 05 января 2012

Возвращение из метода завершает область действия fixed, поэтому указатель больше не фиксируется после возврата.Безопасно передавать фиксированные указатели вверх по цепочке, например,

fixed(TestData* ptr = &data) {
    MyFunction1(ptr);
    MyFunction2(ptr);
}

Но возвращение делает указатель снова нефиксированным.

Логически это имеет смысл: альтернативного пути дляCLR определяет, когда указатель должен стать нефиксированным после того, как вы вернули его из вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...