Хелпикс

Главная

Контакты

Случайная статья





Краткие итоги



Краткие итоги

  1. В языках С и С++ производные типы данных классифицируют в зависимости от построения на производные и непосредственно производные.
  2. Для экономии памяти и времени, затрачиваемого на обращение к данным, в программах используют указатели на объекты.
  3. Указатель не является самостоятельным типом, он всегда связан с другим типом.
  4. Указатель может быть константой или переменной, а также указывать на константу или переменную.
  5. Указатель типа void указывает на область памяти любого размера. Разыменование такого указателя необходимо проводить с операцией приведения типов.
  6. До первого использования в программе объявленный указатель необходимо проинициализировать.
  7. С помощью указателей можно выполнять косвенную адресацию объектов.
  8. Над указателями определены операции: разыменование, взятие адреса, декремент, инкремент, увеличение (уменьшение) на целую константу, разность, определение размера.
  9. Над указателями определены операции сравнения.

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

Указатели используются для динамического выделения памяти компьютера для хранения данных. Динамическое распределение означает, что программа выделяет память для данных во время выполнения.

Память, выделяемая в С функциями динамического распределения данных, находится в так называемой динамически распределяемой области памяти (heap – куча). Динамически распределяемая область памяти – это свободная область памяти, не используемая программой, операционной системой или другими программами. Размер этой области памяти заранее неизвестен, но, как правило, в ней достаточно памяти для размещения данных программы. Хотя размер динамически распределяемой области памяти очень большой, все же она конечна и может быть исчерпана.

Основу системы динамического распределения памяти в С составляют библиотечные функции calloc(), malloc(), realloc() и free().

Рассмотрим прототипы этих функций.

1. Функция calloc()

#include <stdlib.h>

void *calloc(size_t num, size_t size);

Функция calloc() выделяет память, размер которой равен значению выражения num * size, т.е. память, достаточную для размещения массива, содержащего num объектов размером size. Выделенная область памяти обнуляется. Функция calloc() (т.е. результат действия функции) возвращает указатель на первый байт выделенной области памяти для массива num объектов, каждый из которых имеет размер size или NULL, если запрос на память выполнить нельзя. Если для удовлетворения запроса нет достаточного объема памяти, возвращается нулевой указатель. Перед попыткой использовать распределенную память важно проверить, что возвращаемое значение не равно нулю. Тип void может быть переопределен для требуемого типа, т.е. для char, int, float, double.

Пример фрагмента программного кода динамического распределения памяти для массивов заданного размера (например, вводится с клавиатуры):

double *ptr;

ptr = (double *) (calloc(10, sizeof(double)));

if (!ptr) // условие логического отрицания

{printf("Out of memory\n"); exit(1);}

В приведенном примере число 10 – это размер одномерного массива с вещественными данными (типа double ). В случае выделения памяти для двухмерного массива размера N*M строчка с функцией calloc() перепишется так:

ptr = (double *) (calloc(N*M, sizeof(double)));

При этом двухмерный массив рассматривается как аналог одномерного массива размера N*M.

Использование явного приведения типов ( double ) сделано для того, чтобы обеспечить переносимость программы, в первую очередь для обеспечения совместимости с языком программирования С++.

2. Функция  malloc()

#include <stdlib.h>

void *malloc(size_t size);

Функция malloc() возвращает указатель на первый байт области памяти размера size, которая была выделена из динамически распределяемой области памяти. Если для удовлетворения запроса в динамически распределяемой области памяти нет достаточного объема памяти, возвращается нулевой указатель NULL. При этом следует иметь в виду, что попытка использовать нулевой указатель обычно приводит к полному отказу системы. Выделенная область памяти не инициализируется.

Приведем фрагмент программного кода динамического распределения памяти для массивов заданного размера:

double *ptr;

ptr = (double *) (malloc(10*sizeof(double)));

if (!ptr) // условие логического отрицания

{ // выход за пределы памяти

printf("Out of memory. Press any key: ");

_getch();

exit(1);

}

3. Функция realloc()

#include <stdlib.h>

void *realloc(void *ptr, size_t size);

В стандарте С89 функция realloc() изменяет размер блока ранее выделенной памяти, адресуемой указателем *ptr в соответствии с заданным размером size. Значение параметра size может быть больше или меньше, чем перераспределяемая область. Функция realloc() возвращает указатель на блок памяти, поскольку не исключена необходимость перемещения этого блока. В этом случае содержимое старого блока (до size байтов) копируется в новый блок. Если новый размер памяти больше старого, дополнительное пространство не инициализируется. Если запрос невыполним, то функция распределения памяти realloc() возвращает нулевой указатель NULL. Функция realloc() позволяет перераспределить ранее выделенную память. При этом новый размер массива может быть как меньше предыдущего, так и больше его. Если система выделит память в новом месте, то все предыдущие значения, к которым программа обращалась по указателю *ptr, будут переписаны на новое место автоматически.

4. Функция free()

#include <stdlib.h>

void free(void *ptr);

Функция free() возвращает в динамически распределяемую область памяти блок памяти, адресуемый указателем *ptr, после чего эта память становится доступной для выделения в будущем.

Вызов функции free() должен вызываться только с указателем, который был ранее получен в результате вызова одной из функций динамического распределения памяти. Использование недопустимого указателя при вызове, скорее всего, приведет к разрушению механизма управления памятью и, возможно, вызовет крах системы.



  

© helpiks.su При использовании или копировании материалов прямая ссылка на сайт обязательна.