Студопедия — Obsolete 7 страница
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Obsolete 7 страница






Для каждого адреса, вычисленного инициализатором_указателя_fixed, оператор fixed гарантирует, что переменная, находящаяся по этому адресу, не подлежит перемещению или удалению сборщиком мусора на время действия оператора fixed. Например, если адрес, вычисленный инициализатором_указателя_fixed, ссылается на поле объекта или на элемент экземпляра массива, оператор fixed гарантирует, что содержащий экземпляр объекта не будет перемещен или удален в течение срока жизни этого оператора.

На программиста возлагается обязанность обеспечить, чтобы указатели, созданные операторами fixed, не продолжали существовать за пределами выполнения этих операторов. Например, если указатели, созданные операторами fixed, передаются внешним API, программист обязан обеспечить, чтобы в этих API не сохранялась память этих указателей.

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

Пример:

class Test
{
static int x;
int y;

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

static void Main() {
Test t = new Test();
int[] a = new int[10];
unsafe {
fixed (int* p = &x) F(p);
fixed (int* p = &t.y) F(p);
fixed (int* p = &a[0]) F(p);
fixed (int* p = a) F(p);
}
}
}

Эдесь показаны несколько использований оператора fixed. Первый оператор фиксирует и получает адрес статического поля, второй оператор фиксирует и получает адрес поля экземпляра, а третий оператор фиксирует и получает адрес элемента массива. В каждом случае было бы ошибкой использовать обычный оператор &, так как эти переменные классифицируются как перемещаемые переменные.

Четвертый оператор fixed в приведенном выше примере дает тот же результат, что и третий.

В этом примере оператора fixed используется тип string:

class Test
{
static string name = "xx";

unsafe static void F(char* p) {
for (int i = 0; p[i]!= '\0'; ++i)
Console.WriteLine(p[i]);
}

static void Main() {
unsafe {
fixed (char* p = name) F(p);
fixed (char* p = "xx") F(p);
}
}
}

В небезопасном контексте элементы массива в одномерном массиве хранятся в порядке возрастания индекса, начиная с индекса 0 и заканчивая индексом Length – 1. В многомерных массивах элементы хранятся так, что сначала возрастают индексы самого правого измерения, затем соседнего левого и так далее влево. В пределах оператора fixed, получающего указатель p на экземпляр массива a, значения указателя в диапазоне от p до p + a.Length - 1 представляют адреса элементов массива. Аналогично переменные в диапазоне от p[0] до p[a.Length - 1] представляют фактические элементы массива. При данном способе хранения массивов можно обращаться с массивом любого измерения как если бы он был линейным.

Пример:

using System;

class Test
{
static void Main() {
int[,,] a = new int[2,3,4];
unsafe {
fixed (int* p = a) {
for (int i = 0; i < a.Length; ++i) // treat as linear
p[i] = i;
}
}

for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 4; ++k)
Console.Write("[{0},{1},{2}] = {3,2} ", i, j, k, a[i,j,k]);
Console.WriteLine();
}
}
}

В результате получается:

[0,0,0] = 0 [0,0,1] = 1 [0,0,2] = 2 [0,0,3] = 3
[0,1,0] = 4 [0,1,1] = 5 [0,1,2] = 6 [0,1,3] = 7
[0,2,0] = 8 [0,2,1] = 9 [0,2,2] = 10 [0,2,3] = 11
[1,0,0] = 12 [1,0,1] = 13 [1,0,2] = 14 [1,0,3] = 15
[1,1,0] = 16 [1,1,1] = 17 [1,1,2] = 18 [1,1,3] = 19
[1,2,0] = 20 [1,2,1] = 21 [1,2,2] = 22 [1,2,3] = 23

В примере

class Test
{
unsafe static void Fill(int* p, int count, int value) {
for (; count!= 0; count--) *p++ = value;
}

static void Main() {
int[] a = new int[100];
unsafe {
fixed (int* p = a) Fill(p, 100, -1);
}
}
}

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

В примере:

unsafe struct Font
{
public int size;
public fixed char name[32];
}

class Test
{
unsafe static void PutString(string s, char* buffer, int bufSize) {
int len = s.Length;
if (len > bufSize) len = bufSize;
for (int i = 0; i < len; i++) buffer[i] = s[i];
for (int i = len; i < bufSize; i++) buffer[i] = (char)0;
}

Font f;

unsafe static void Main()
{
Test test = new Test();
test.f.size = 10;
fixed (char* p = test.f.name) {
PutString("Times New Roman", p, 32);
}
}
}

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

Значение char*, созданное фиксацией экземпляра строки, всегда указывает на строку, оканчивающуюся символом null. В пределах оператора fixed, получающего указатель p на экземпляр строки s, значения указателя в диапазоне от p до p + s.Length - 1 представляют адреса символов в строке, а значение указателя p + s.Length всегда указывает на символ null (символ со значением '\0').

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

Автоматическое завершение строк символом null особенно удобно при вызове внешних API, ожидающих строки «в стиле C». Отметьте, однако, что в экземпляре строки могут содержаться символы null. Если символы null имеются, то строка будет выглядеть усеченной, если обращаться с ней как с завершающейся символом null строкой char*.

18.7 Буферы фиксированного размера

Буферы фиксированного размера используются для объявления «в стиле C» линейных массивов как членов структур, главным образом они полезны для связи с неуправляемыми API.

18.7.1 Объявления буферов фиксированного размера

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

объявление_члена_структуры:

объявление_буфера_фиксированного_размера

объявление_буфера_фиксированного_размера:
атрибутынеобязательно модификаторы_буфера_фиксированного_размеранеобязательно fixed тип_элемента_буфера
деклараторы_буфера_фиксированного_размера;

модификаторы_буфера_фиксированного_размера:
модификатор_буфера_фиксированного_размера
модификатор_буфера_фиксированного_размера модификаторы_буфера_фиксированного_размера

модификатор_буфера_фиксированного_размера:
new
public
protected
internal
private
unsafe

тип_элемента_буфера:
тип







Дата добавления: 2015-09-07; просмотров: 408. Нарушение авторских прав; Мы поможем в написании вашей работы!



Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...

Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

Подкожное введение сывороток по методу Безредки. С целью предупреждения развития анафилактического шока и других аллергических реак­ций при введении иммунных сывороток используют метод Безредки для определения реакции больного на введение сыворотки...

Принципы и методы управления в таможенных органах Под принципами управления понимаются идеи, правила, основные положения и нормы поведения, которыми руководствуются общие, частные и организационно-технологические принципы...

ПРОФЕССИОНАЛЬНОЕ САМОВОСПИТАНИЕ И САМООБРАЗОВАНИЕ ПЕДАГОГА Воспитывать сегодня подрастающее поколение на со­временном уровне требований общества нельзя без по­стоянного обновления и обогащения своего профессио­нального педагогического потенциала...

Огоньки» в основной период В основной период смены могут проводиться три вида «огоньков»: «огонек-анализ», тематический «огонек» и «конфликтный» огонек...

Упражнение Джеффа. Это список вопросов или утверждений, отвечая на которые участник может раскрыть свой внутренний мир перед другими участниками и узнать о других участниках больше...

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

Studopedia.info - Студопедия - 2014-2024 год . (0.009 сек.) русская версия | украинская версия