2011-12-31 13 views
5
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(); 
} 

Da el error que la referencia del objeto no se establece en la instancia de un objeto. ¿Cómo puedo hacerlo cuando quiero hacer Programa árbol AVL (que he creado y probado en C++ pero la copia en C# da error)Inicialización del puntero de secuencia en C#

+0

_What_ da el error? No veo ningún código que sea erróneo. – Oded

+12

¿Por qué estás usando 'inseguro'? Copiar el código de C++ no te llevará muy lejos. ¿Estás seguro de que no quieres una 'clase' (en C#, esto significa tipo de referencia, que permite valores' null') en lugar de una 'struct' (en C#, esto significa tipo de valor, que siempre se copia por valor y no tiene concepto de 'nulo')? – bobbymcr

Respuesta

4

El problema es con la línea:

Node* T=new Node(); 

En C#, new Node() devuelve Node (que es referencia), no Node* (que es puntero). En su lugar, debe usar stackalloc.

De todos modos, por favor no copiar C++ y C# hacerlo así!

+0

Encontré ese también. Sin embargo, eso no da 'Referencia de objeto no configurada para instancia de un objeto' sino una excepción de conversión no válida. – rene

2

No se puede asignar una variable de .NET a un puntero sólo se puede tomar su dirección. Si no hace referencia a new ed Node, obtiene la basura recolectada inmediatamente, por lo tanto, es probable que haya encontrado "referencia de objeto no establecida". Expresión como Node* T = new Node() no debe compilar sin embargo, ya que efectivamente intenta hacer una conversión de tipo no válido.

Lo que estamos tratando de hacer es erróneo: no copiar y pegar el código C++ a C#, esto no tiene sentido. Si ya obtuviste los componentes C++ probados utiliza interoperabilidad .NET/no gestionada para calcular los datos entre los dos mundos, aunque no recomendaría hacerlo en este nivel de abstracción. Si está haciendo un ejercicio, implemente un árbol AVL en el mundo .NET solamente; de ​​lo contrario, use una de las colecciones de marcos con funcionalidades equivalentes, p. SortedSet o SortedDictionary ...

+0

Dado que Node es una estructura, no se recolecta basura en absoluto, simplemente; esa dirección en la pila probablemente se reutilizará en breve –

+0

Correcto, mea culpa: Debería haber leído dos veces antes de publicar. –

17

No intente utilizar punteros en C# como este. Si está portando código C++ que usa punteros como referencias, en su lugar use tipos de referencia. Tu código no funcionará en absoluto; "nuevo" no asigna estructuras del montón, por un lado, e incluso si lo hizo , los punteros deben fijarse en el lugar en C#; C# es un lenguaje recogido de basura.

En resumen nunca use unsafe a menos que comprenda a fondo todo lo que hay que saber sobre la gestión de la memoria en C#. Está apagando el sistema de seguridad que está ahí para protegerlo, y por lo tanto debe saber lo que hace ese sistema de seguridad.

El código debe ser:

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; 
    } 
}