Сброс указателя один раз вызвал метод второй раз - PullRequest
0 голосов
/ 17 мая 2019

Может кто-нибудь объяснить, почему голова и хвост сбрасываются в ноль, как только секунда вызывает IsAMatch, хотя id передает новые указатели на него, старые получают сброс.

У меня есть эквивалентный скрипт на c ++, и он работаетотлично.

Есть идеи?
мой код

маленький пример кода здесь печатается 10,20, поэтому второй вызов изменяет первую структуру

class Program
{
    static unsafe void Main(string[] args)
    {

        MyStruct* myStruct = null;

        ChangeMe(ref myStruct, 10);

        Console.WriteLine(myStruct->num);

        MyStruct* myStruct2 = null;
        ChangeMe(ref myStruct2,20);

        Console.WriteLine(myStruct->num);

        Console.ReadKey();
    }

    public static unsafe void ChangeMe(ref MyStruct* h, int v)
    {
        MyStruct myStructNew = new MyStruct(v);

        h = &myStructNew;
    }

    public unsafe struct MyStruct
    {
        public int num;

        public MyStruct(int n)
        {
            num = n;
        }
    }
}

1 Ответ

2 голосов
/ 17 мая 2019

Вы в основном возвращаете указатель на локальную переменную, что совершенно неправильно.

Существует различие в ключевом слове C # new и ключевом слове C ++ new, точнее, в его взаимодействии с class и struct в C #. В C ++ new всегда означает выделение в куче, которую вам нужно вручную отменить. В C # new вызов на class означает выделение кучи, но new вызов на struct просто инициализирует локальную переменную.

Этот код C #:

MyStruct myStructNew = new MyStruct(v);

эквивалентен этому коду C ++

MyStruct myStructNew{v};
Ключевое слово

C # struct создает тип значения, что означает, что в вашем случае оно размещается в стеке. Затем после возврата из ChangeMe стек уменьшается, освобождая локальные переменные. При втором вызове стек снова увеличивается, выделяя локальные переменные для второго вызова. Поскольку вы вызываете один и тот же метод, та же самая позиция стека будет использоваться для второго MyStruct myStructNew.

...