2011-12-31 16 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(); 
} 

Segnala errore che il riferimento all'oggetto non è impostato su istanza di un oggetto. Come posso farlo quando voglio fare AVL Programma Albero (che ho creato e testato in C++, ma la copia in C# dà errore)Inizializzazione puntatore stringa in C#

+0

_What_ dà l'errore? Non vedo _any_ codice che farebbe un errore. – Oded

+12

Perché stai usando 'non sicuro? Copiare il codice da C++ non ti porterà molto lontano. Sei sicuro di non volere un 'class' (in C#, questo significa tipo di riferimento, che consente valori' null') invece di un 'struct' (in C#, questo significa tipo di valore, che viene sempre copiato dal valore e non ha concetto di 'null')? – bobbymcr

risposta

4

Il problema è con la linea:

Node* T=new Node(); 

In C#, new Node() restituisce Node (che è il riferimento), non Node* (che è puntatore). Dovresti usare stackalloc, invece.

Ad ogni modo, per favore non copiare C++ e farlo C# way!

+0

L'ho trovato anch'io. Tuttavia, ciò non fornisce "il riferimento all'oggetto non impostato sull'istanza di un oggetto" ma un'eccezione di cast non valida. – rene

2

Non è possibile assegnare una variabile .NET a un puntatore, è possibile solo prendere il suo indirizzo. Se non si fa riferimento a e viene immediatamente recuperata la garbage collection, è probabile che sia stato eseguito il "riferimento all'oggetto non impostato". Espressione come Node* T = new Node() non dovrebbe tuttavia compilare, poiché tenta in modo efficace di eseguire una conversione di tipo non valido.

Quello che stai cercando di fare è sbagliato: non copiare e incollare il codice C++ in C#, questo non ha senso. Se hai già testato componenti C++ usa l'interoperabilità .NET/non gestito per effettuare il marshalling dei dati tra i due mondi, sebbene non consiglierei di farlo a questo livello di astrazione. Se stai facendo un esercizio, implementa un albero AVL solo in mondo .NET, altrimenti usa uno degli insiemi di framework con funzionalità equivalenti, ad es. SortedSet o SortedDictionary ...

+0

Dato che il nodo è una struttura, non è affatto garbage collection - semplicemente; quell'indirizzo sulla pila è probabile che sarà riutilizzato a breve –

+0

Giusto, mea culpa: avrei dovuto leggere due volte prima di postare. –

17

Non provare a utilizzare i puntatori in C# come questo. Se si esegue il porting del codice C++ che utilizza i puntatori come riferimenti, utilizzare invece i tipi di riferimento. Il tuo codice non funzionerà affatto; "nuovo" non assegna le strutture dall'heap, per una cosa, e anche se lo ha fatto, i puntatori devono essere posizionati in posizione in C#; C# è una lingua raccolta dalla spazzatura.

In breve non utilizzare mai unsafe a meno che non si comprenda completamente tutto ciò che è necessario sapere sulla gestione della memoria in C#. Stai spegnendo il sistema di sicurezza che è lì per proteggerti, e quindi devi sapere cosa fa quel sistema di sicurezza.

Il codice dovrebbe essere:

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