c # Что произойдет, если span <T>(memory <T>) ссылается на буферы в стеке - PullRequest
0 голосов
/ 01 декабря 2018

.NET Standard 2.1 представил новую функцию, позволяющую «управлять» блоками памяти вместо их копирования: Диапазон или Память .

ВНапример, я заметил, что можно сослаться на буфер стека:

byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
   stackSpan[ctr] = data++;

Насколько я знаю, стековая память для процесса ограничена (1 МБ или 4 МБ), и мы не можем освободить ее вручную.

Итак, я думаю, что создание Memory<T> или Span<T> каким-то образом "закрепит" ячейку памяти в стеке, и мы сможем ее проиндексировать?Но разве это не потенциальный случай утечки стека, который может привести к переполнению стека?Поскольку массив в стеке должен жить как Memory<T> или Span<T>.

1 Ответ

0 голосов
/ 01 декабря 2018

Это безопасно, поскольку время жизни Span будет таким же или короче, чем у массива, выделенного из стека.

Вы не можете назначить результат stackalloc для Memory<T> по крайней мере напрямую (я даже не думаю, чтонебезопасный код может помочь - C #: преобразовать универсальный указатель в массив ), так что область видимости просто равна Span<T>.

В соответствии с ссылкой , которую вы опубликовали в жизни Spanпривязан к определенной области:

Span<T> - это структура ref, которая размещается в стеке, а не в управляемой куче.Типы ref структуры имеют ряд ограничений, чтобы гарантировать, что они не могут быть переведены в управляемую кучу,

Обратите внимание, что ref struct запрещает некоторые операции, в том числе ту, о которой вы должны беспокоиться - возврат Span<T> из метода, где был выделен стек.В результате диапазон результатов будет уничтожен в одно и то же время (или ранее), а затем стековый фрейм, включающий массив, созданный stackalloc.

   static Span<byte> MySpan()
   {
        Span<byte> span = stackalloc byte[100];
        // error CS8352: Cannot use local 'span' in this context because it may 
        // expose referenced variables outside of their declaration scope
        return span;
    }

. Это также описано в статье журнала MSDN (январь 2018 г.) C #- Все о Span: Изучение нового .NET Mainstay Стивеном Тубом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...