Почему разрешено возвращать небезопасные указатели из функции? - PullRequest
2 голосов
/ 22 февраля 2009

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

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

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

Ответы [ 2 ]

3 голосов
/ 22 февраля 2009

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

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

2 голосов
/ 22 февраля 2009

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

...