П'ятниця, 19.04.2024, 22:50
Гость

Мішатронік

Мобільна версія | Додати у вибране  | Мій профіль | Вихід | RSS |
Меню сайту
Наше опитування
Чи знаєте вы Java
Всього відповідей: 3
Статистика

Онлайн всього: 1
Гостей: 1
Користувачів: 0


Создание динамических объектов

По стандарту аргументы функций malloc, calloc имеют тип возвращаемого объекта void*.

 
char *s = (char*)malloc(size);
unsigned size; /* объем памяти, который необходимо выделить */
char *s = (char *)calloc(nelem,elsize);
unsigned nelem; /* число элементов, для которых нужно выделить память */
unsigned elsize; /* объем памяти, который необходимо выделить для каждого элемента */
/* либо просто заменив char* на void* */
void* calloc(nelem, elsize);
unsigned nelem;
unsigned elsize;
 

Обе функции возвращают указатель на выделенную память. Для определения необходимого объема памяти можно использовать оператор sizeof:

 
sizeof (выражение)
 

Объем памяти, необходимый для хранения выражения:

 
sizeof(T)
 

Объем памяти, необходимый для хранения значений типа T.

 

Функции malloc и calloc возвращают указатель на созданный динамический объект. Фактически функции возвращают знаковые указатели, которые могут быть явно преобразованы к подходящему типу указателя. Значения, возвращенные функциями распределения памяти, используются для ссылок на динамические объекты. Например, с помощью оператора

 
pi = (int *) malloc(sizeof(int));
 

выделяется память для одного целого значения. Адрес этой области памяти присваивается переменной pi после его преобразования из типа char * (указатель на знак), с которым он возвращается функцией malloc, к типу int * (указатель на целое), т.е. типу переменной pi.

 

Доступ к динамическим объектам

Присваивание значения объекту, ссылка на который задана указателем pi, выполняется с помощью имени указателя *pi, например:

 
*pi = 55;
 

Одно и то же значение может быть присвоено более чем одной переменной-указателю. Таким образом, можно ссылаться надинамический объект с помощью более одного указателя. Про объект, к которому можно обращаться с использованием более чем одного указателя, говорят, что он имеет псевдоимена ( alias ). Например, в результате присваивания

 
qi = pi;
 

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

 

Время жизни динамического объекта

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

 
free(ptr)
char *ptr;
 

Необходимо предпринимать меры предосторожности для избежания ошибок, связанных со ссылками на объектпамять для которого уже освобождена - проблема висящей ссылки (Horowwitz, E. 1983. Fundamentals of Programming Languages. Computer Science Press).

 

Если реализация языка обеспечивает сборку мусора, то память, занимаемая объектами, к которым невозможен доступ, может быть автоматически подготовлена для повторного использования. Однако в языке Си, в отличие от языков Лисп и Снобол, такая возможность отсутствует.

 

Указание на заранее определенные объекты. Указатели могут обеспечивать ссылку на заранее определенные объекты. Адрестакого объекта может быть определен использованием оператора адресации & ( address of operator ). Например, рассмотрим переменные i и pi, определенные как

 
int i, *pi;
 

Присваивание

 
pi = &i;
 

pi позволяет ссылаться на объект с именем i также с помощью указателя pi, используя обозначение *pi. Имена i и *pi -псевдоимена. Оператор & является также стандартным средством моделирования передачи параметров по ссылке. Однако его употребление может привести к проблеме висящей ссылки.

 

Указание на произвольную ячейку памяти. С помощью явных преобразований можно получить указатель на произвольную ячейку памяти. Например, предположим, что pt является указателем типа T*. Тогда указатель на ячейку памяти 0777000 можно получить с помощью следующей записи:

 
pt = (T*)0777000;
 

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

 

Связь между указателями и массивами

В языке Си массивы и указатели тесно связаны. Имя каждого массива может рассматриваться как указатель на первый элементмассива. Элемент массива a[i] есть элемент массива, на который указывает значение a+i, т.е. *(a+i), где значение а является адресом первого элемента массива а, а именно a[0]Выражение a+i является примером арифметических действий с указателями - целое значение i складывается со значением указателя, адресом первого элемента массива аЗначение этого выражения есть а плюс объем памяти, занимаемый i элементами массива a. Предположим, что x - двумерный массив. Тогдассылка на подмассив x[i] является ссылкой на i-ю строку массива xx[i] дает адрес первого элемента этой строки, т.е. *(x+i). Элементы каждой строки занимают непрерывную область памяти, так как массивы хранятся записанными по строкам, т.е. при записи элементов массива в память быстрее всех изменяется последний индекс.

 

Аналогично, ссылка на y[i], где y - n-мерный ( n>1 ) массив, является ссылкой на ( n-1 )-мерный подмассив с элементамиy[i, j2,j3,_jn], где значения jk соответствуют определению массива yy[i] дает адрес первого элемента этого подмассива, т.е. *(y+i). Все элементы этого ( n-1 )-мерного подмассива занимают непрерывную область памяти.

 

Форма входа
Пошук
Друзі сайту
Календар
«  Квітень 2024  »
ПнВтСрЧтПтСбНд
1234567
891011121314
15161718192021
22232425262728
2930

Єдина Країна! Единая Страна!