Почему разрешено возвращать небезопасные указатели внутри функции?


2

Я недавно увидел пару проектов с открытым исходным кодом, которые на самом деле это делают; верните небезопасный указатель из функции, такой как: «int * input = this.someIterator.GetUnsafePtr()».

Из моего понимания это должно быть совершенно неправильно. Небезопасные указатели могут быть получены только с помощью «фиксированных» заявлений, и, конечно, те, которые возвращаются из функции, больше не будут закреплены (они «потеряют» свою область объявления), в результате чего они, в конечном счете, будут собраны в мусор.

Но тогда я не помню, чтобы компилятор также предупреждал об этом, так зачем же использовать фиксированный оператор, если на самом деле у вас есть «незакрепленные» указатели?

2

Я никогда не видел таких конструкций в проектах с открытым исходным кодом. Будет лучше, если вы предоставите некоторые примеры такого использования в своем вопросе. Значение этого может зависеть от поведения.
Но я согласен, что небезопасные указатели являются злыми и должны использоваться только при взаимодействии с некоторыми родными библиотеками или кодом.
Насколько я помню, вы можете использовать эту конструкцию только в небезопасном блоке. Поэтому я думаю, что компилятор здесь не будет предупреждать. И ИМО лучше использовать IntPtr (небезопасные блоки могут выполняться только в полном доверии).
EDIT:
@ Стефен прав, IntPtr не будет ссылаться на объект в коллекции GC.

  0

IntPtr не является указателем отслеживания. Если IntPtr ссылается на управляемый объект и этот объект перемещается, указатель не обновляется. Нет никакой реальной разницы между IntPtr и небезопасным указателем, отличным от того, что IntPtr является CLS-совместимым, а не «небезопасным». 22 фев. 092009-02-22 13:16:28

  0

Вы правы, спасибо. Я думаю, что мне нужно снова прочитать о CLR. 22 фев. 092009-02-22 13:49:24


3

Как насчет Marshal.AllocHGlobal или Marshal.AllocCoTaskMem, как возвращение IntPtr, которые могут быть свободно отливать в void * с помощью функции .ToPointer()?

Или указатель может исходить из неуправляемого кода. Вам нужна память fix/pin, потому что память управляется, поэтому до тех пор, пока она не fixed/pinned, сборщик мусора может свободно его перемещать, делая указатель недействительным.