2014-09-11 4 views
2

со следующими кодами:Почему мы не можем взять указатель на строку?

static unsafe void Main(string[] args) 
{ 
    int a = 5; 
    IntPtr pa = new IntPtr(&a); // no error 
    var xa = pa.ToPointer(); 

    string b = "test"; 
    IntPtr pb = new IntPtr(&b); // compile error 
    var xb = pb.ToPointer(); 
} 

Он генерирует ошибку компиляции:

Не могу взять адрес, получить размер или объявить указатель на управляемый тип («типа»)

Что случилось с указателем на управляемый тип?

+1

Возможный дубликат [Невозможно принять адрес, получить размер или объявить указатель на управляемый тип] (http://stackoverflow.com/ вопросы/13299153/can not-take-the-address-of-get-the-size-of-or-declare-a-pointer-to-a-managed-t) –

+1

Возможный дубликат [make IntPtr в C# .NET point to string value] (http://stackoverflow.com/questions/11090427/make-intptr-in-c-net-point-to-string-value) –

+1

Компилятор на 100% убежден, что вы не можете разыменовать IntPtr правильно. Правильно, строка может быть уничтожена в любой момент, наносекунды после того, как вы инициализировали IntPtr. Сборщик мусора .NET - это * не * консервативный коллекционер. –

ответ

1

Причина в том, что управляемые объекты могут перемещаться в памяти как побочный эффект сборки мусора других объектов, тем самым аннулируя любые указатели на них.

int Вы берете адрес, находящийся в стеке, и не будете перемещаться в памяти - таким образом, безопасно получить доступ к указателю на него. (Ну, так же безопасно, как с помощью указателей, может быть ...)