Nano Hash - криптовалюты, майнинг, программирование

Фиксированный указатель небезопасного кода С#, переданный в качестве параметра

Я наткнулся на следующий код на msdn:

        unsafe static void SquarePtrParam (int* p) 
        {
            *p *= *p;
        }

        unsafe static void Main() 
        {
            Point pt = new Point();
            pt.x = 5;
            pt.y = 6;
            // Pin pt in place:
            fixed (int* p = &pt.x) 
            {
                SquarePtrParam (p);
            }
            // pt now unpinned.
            Console.WriteLine ("{0} {1}", pt.x, pt.y);
        }

Мне просто интересно, мы напрямую обращаемся к указателю в функции SquarePtrParam, наследует ли он информацию о том, что массив исправлен из вызывающего метода?

Почему бы нам не указать явно fixed локально в SquarePtrParam.

Думаю, мне не помешали бы некоторые уточнения по поводу этого оператора fixed.

11.11.2011

Ответы:


1

Фиксированный оператор реализует открепление области памяти так же, как оператор "using" закрывает открытые файлы в конструкции using(FileStream stream = new FileStream(..)). Память будет закреплена до тех пор, пока вы не покинете фиксированный блок кода.

В коде IL он создаст фиктивную локальную переменную PINNED и сохранит в ней указатель. Это не позволит GC переместить область памяти, содержащую этот указатель. После того, как вы покинете фиксированный блок, он сохранит ноль в этой переменной PINNED. Именно так:

public static unsafe void TestInternal(byte* pointer)
{
    Console.WriteLine((IntPtr)pointer);
}

public static void FixedDemo()
{
    Byte[] newArray = new Byte[1024];

    unsafe
    {
        fixed (Byte* pointer = &newArray[0])
        {
            TestInternal(pointer);
        }
    }

    Console.WriteLine("Test Complete");
}

Итак, FixedDemo в IL-коде:

.method public hidebysig static void  FixedDemo() cil managed
{
  // Code size       47 (0x2f)
  .maxstack  2
  .locals init ([0] uint8[] newArray,
           [1] uint8& pinned pointer)
  IL_0000:  nop
  IL_0001:  ldc.i4     0x400 // Put 1024 on the stack
  IL_0006:  newarr     [mscorlib]System.Byte // allocate new array of 1024 length
  IL_000b:  stloc.0    // Store it in local variable 0
  IL_000c:  nop 
  IL_000d:  ldloc.0    // Put local variable 0 on the stack
  IL_000e:  ldc.i4.0   // Put zero on the stack
  IL_000f:  ldelema    [mscorlib]System.Byte // Load address of zero index from array
  IL_0014:  stloc.1    // !!! Here we pin memory by storing it in pinned variable
  IL_0015:  nop
  IL_0016:  ldloc.1    // Load function argument
  IL_0017:  conv.i     // Perform conversion 
  IL_0018:  call       void FinMath.Tests.Program::TestInternal(uint8*)
  IL_001d:  nop
  IL_001e:  nop
  IL_001f:  ldc.i4.0   // Load zero on the stack
  IL_0020:  conv.u     // Perform conversion 
  IL_0021:  stloc.1    // !!!! Here we unpin memory
  IL_0022:  nop
  IL_0023:  ldstr      "Test Complete" // Load string
  IL_0028:  call       void [mscorlib]System.Console::WriteLine(string) // Out message
  IL_002d:  nop
  IL_002e:  ret
} // end of method Program::FixedDemo

Для получения дополнительной информации посетите:

  1. MSDN

  2. Журнал MSDN: Сборка мусора: автоматическое управление памятью в Microsoft .NET Framework

  3. Общеязыковый стандарт среды выполнения ECMA 335 Раздел III, 1.1.4.2 Управляемый Указатель (тип &)

11.11.2011

2

наследует ли он информацию о том, что массив исправлен от вызывающего метода?

Нет, эта информация не нужна. Все, что он знает, это то, что ему был передан указатель. Один из способов получения указателя — через оператор fixed, но есть и другие способы (например, путем преобразования IntPtr), и любые такие совместимые указатели также могут быть переданы в SquarePtrParam.

11.11.2011
  • tbh Мне тоже нравится этот ответ, потому что действительно, как только метод получил указатель в качестве параметра, он не особо заботится о других вещах. 15.11.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..