Инициализация указателя структуры в C # - PullRequest
5 голосов
/ 31 декабря 2011
unsafe public class Temp
{
    public struct Node
    {
        Node *left;
        Node *right;
        int value;
    }

    public Temp()
    {
        Node* T=new Node();
        T->left=null;
        T->right=null;
        T->value=10;
    }
}

main()
{
    Temp temp=new Temp();
}

Выдает ошибку, что ссылка на объект не установлена ​​на экземпляр объекта. Как я могу сделать это, когда я хочу создать AVL Tree Program (которую я создал и протестировал на C ++, но копирование в C # дает ошибку)

Ответы [ 3 ]

17 голосов
/ 31 декабря 2011

Не пытайтесь использовать указатели в C #, как это.Если вы переносите код C ++, который использует указатели в качестве ссылок, вместо этого используйте ссылочные типы.Ваш код не будет работать вообще;«new» не выделяет структуры из кучи, с одной стороны, и даже если он это сделал, указатели должны быть закреплены на месте в C #;C # - это язык для сборки мусора.

Короче говоря никогда не используйте unsafe, если вы не полностью понимаете все, что нужно знать об управлении памятью в C # .Вы отключаете систему безопасности, которая должна вас защитить, и поэтому вы должны знать, что делает эта система безопасности.

Код должен быть:

public class Temp // safe, not unsafe
{
    public class Node // class, not struct
    {
        public Node Left { get; set; } // properties, not fields
        public Node Right { get; set; } 
        public int Value { get; set; }
    }

    public Temp()
    {
        Node node = new Node();
        node.Left = null; // member access dots, not pointer-access arrows
        node.Right = null;
        node.Value = 10;
    }
}
4 голосов
/ 31 декабря 2011

Проблема со строкой:

Node* T=new Node();

В C # new Node() возвращает Node (это ссылка), а не Node* (это указатель).Вместо этого вы должны использовать stackalloc .

В любом случае, пожалуйста, не копируйте C ++ и делайте это C # способом!

2 голосов
/ 31 декабря 2011

Вы не можете назначить переменную .NET указателю, вы можете взять только его адрес. Если вы не ссылаетесь на new ed Node, он сразу же собирает мусор, поэтому вы, вероятно, натолкнулись на «ссылка на объект не установлена». Однако выражение типа Node* T = new Node() не должно компилироваться, поскольку оно фактически пытается выполнить недопустимое преобразование типа.

То, что вы пытаетесь сделать, неверно: не копируйте и не вставляйте код C ++ в C #, это чепуха. Если вы уже тестировали компоненты C ++, используйте .NET / неуправляемое взаимодействие для объединения данных между двумя мирами, хотя я бы не рекомендовал делать это на этом уровне абстракции. Если вы выполняете упражнение, реализуйте дерево AVL только в мире .NET, в противном случае используйте одну из коллекций инфраструктуры с эквивалентной функциональностью, например, SortedSet или SortedDictionary ...

...