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

개체 참조가 개체의 인스턴스로 설정되지 않는다는 오류가 발생합니다. 나는 그것을 할 수 있습니다 어떻게 AVL 트리 프로그램을 만들고 싶어 할 때 (나는 C에서 생성하고 테스트 한 ++ 있지만 C#에서 복사주는 오류)C에서 구조 포인터 초기화

+0

_What_ 오류를 준다? 오류가되는 _any_ 코드가 표시되지 않습니다. – Oded

+12

왜 안전하지 않습니까? C++에서 코드를 복사하는 것은 당신을 아주 멀리하지 않을 것입니다. C#에서는'struct' 대신에'null' 값을 허용하는 참조 타입을 의미합니다. (C#에서는 항상 값으로 복사되는 값 타입을 의미합니다. 'null'에 대한 개념이 없다)? – bobbymcr

답변

4

문제는 라인입니다 : C#에서

Node* T=new Node(); 

, new Node()Node (참조)이며 Node* (포인터는 아닙니다)을 반환합니다. 대신 stackalloc을 사용해야합니다.

어쨌든 C++을 복사하지 말고 C#으로 해주세요!

+0

나는 그것도 발견했다. 그러나 '개체 참조가 개체의 인스턴스로 설정되지 않음'을 제공하지는 않지만 잘못된 캐스트 예외가 발생합니다. – rene

2

포인터 만 .NET 변수를 할당 할 수는 있지만 주소는 가져갈 수 없습니다. new ed Node을 참조하지 않으면 가비지 수집이 즉시 이루어 지므로 "객체 참조가 설정되지 않았습니다"라는 메시지가 나타납니다. Node* T = new Node()과 같은 식은 유효하지 않은 형식 변환을 효과적으로 시도하기 때문에 컴파일하지 않아야합니다.

당신이하려는 것은 잘못되었습니다. C++ 코드를 복사하여 C#에 붙여 넣지 마십시오. 이것은 말도 안됩니다. 이미 테스트를 거친 경우 C++ 구성 요소는 .NET/관리되지 않는 interop을 사용하여 두 세계 간 데이터를 마샬링합니다. 그러나이 추상화 수준에서는 수행하지 않는 것이 좋습니다. 연습을하고 있다면 .NET 세계에서만 AVL 트리를 구현하십시오. 그렇지 않으면 프레임 워크 컬렉션 중 하나를 동일한 기능을 가진 예 1과 같이 사용하십시오. SortedSet 또는 SortedDictionary ...

+0

Node는 구조체이므로 아무 것도 가비지 수집되지 않습니다. 그 스택상의 주소는 곧 재사용 될 것입니다. –

+0

맞습니다. mea culpa : 게시하기 전에 두 번 읽어야합니다. –

17

이와 같이 C#에서는 포인터를 사용하지 마십시오. 포인터를 참조로 사용하는 C++ 코드를 이식하는 경우 대신 참조 유형을 사용하십시오. 코드가 전혀 작동하지 않습니다. "new"는 힙에서 구조체를 할당하지 않으며, 심지어 수행 한 경우에도 포인터는 C#의에 고정해야합니다. C#은 가비지 수집 언어입니다.

짧게는 을 사용하십시오. C#에서 메모리 관리에 대해 알아야 할 모든 것을 완전히 이해하지 못하면 unsafe을 절대 사용하지 마십시오. 당신은 당신을 보호하기 위해 거기에있는 안전 시스템을 끄고, 그래서 당신은 그 안전 시스템이 무엇을하는지 알아야합니다.

코드가 있어야한다 :

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