<< Предыдущая Оглавление Следующая >>


4.2. Функции malloc() и free(). Ссылки

Каждый раз при инициализации указателя использовался адрес той или иной переменной. Это было связано с тем, что компилятор языка С++ автоматически выделяет память для хранения переменных и с помощью указателя можно без последствий работать с этой выделенной областью. Вместе с тем существуют функции malloc() и free(), позволяющие выделять и освобождать память по мере необходимости. Данные функции находятся в библиотеке и имеют следующий синтаксис:

void* malloc(size_t); //функция выделения памяти
void free(void* memblock); //функция освобождения памяти

Здесь size_t – размер выделяемой области памяти в байтах; void* - обобщенный тип указателя, т.е. не привязанный к какому-либо конкретному типу. Рассмотрим работу данных функций на примере выделения памяти для 10 элементов типа double.

Листинг 4.3. Программирование динамического массива.

#include
#include
int main()
{
double* ptd;
ptd = (double *)malloc(10 * sizeof(double));
if(ptd != NULL)
{
for(int i = 0;i < 10;i++)
ptd[i] = i;
} else printf(“Не удалось выделить память.”);
free(ptd);
return 0;
}

При вызове функции malloc() выполняется расчет необходимой области памяти для хранения 10 элементов типа double. Для этого используется функция sizeof(), которая возвращает число байт, необходимых для хранения одного элемента типа double. Затем ее значение умножается на 10 и в результате получается объем для 10 элементов типа double. В случаях, когда по каким-либо причинам не удается выделить указанный объем памяти, функция malloc() возвращает значение NULL. Данная константа определена в нескольких библиотеках, в том числе в и . Если функция malloc() возвратила указатель на выделенную область памяти, т.е. не равный NULL, то выполняется цикл, где записываются значения для каждого элемента. При выходе из программы вызывается функция free(), которая освобождает ранее выделенную память. Формально, программа написанная на языке С++ при завершении сама автоматически освобождает всю ранее выделенную память и функция free(), в данном случае, может быть опущена. Однако при составлении более сложных программ часто приходится много раз выделять и освобождать память. В этом случае функция free() играет большую роль, т.к. не освобожденная память не может быть повторно использована, что в результате приведет к неоправданным затратам ресурсов ЭВМ.

Использование указателей досталось в "наследство" от языка С. Чтобы упростить процесс изменения параметров в С++ вводится такое понятие как ссылка. Ссылка представляет собой псевдоним (или второе имя), который программы могут использовать для обращения к переменной. Для объявления ссылки в программе используется знак & перед ее именем. Особенность использования ссылок заключается в необходимости их инициализации сразу же при объявлении, например:

int var;
int &var2 = var;

Здесь объявлена ссылка с именем var2, которая инициализируется переменной var. Это значит, что переменная var имеет свой псевдоним var2, через который возможно любое изменение значений переменной var. Преимущество использования ссылок перед указателями заключается в их обязательной инициализации, поэтому программист всегда уверен, что переменная var2 работает с выделенной областью памяти, а не с произвольной, что возможно при использовании указателей. В отличие от указателей ссылка инициализируется только один раз, при ее объявлении. Повторная инициализация приведет к ошибке на стадии компиляции. Благодаря этому обеспечивается надежность использования ссылок, но снижает гибкость их применения. Обычно ссылки используют в качестве аргументов функций для изменения передаваемых переменных внутри функций. Следующий пример демонстрирует применение такой функции:

Листинг 4.4. Пример использования ссылок.

void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int agr1 = 10, arg2 = 5;
swap(arg1, arg2);
return 0;
}

В данном примере функция swap() использует два аргумента, представляющие собой ссылки на две переменные. Используя имена ссылок a и b, осуществляется манипулирование переменными arg1 и arg2, заданных в основной функции main() и переданных как параметры функции swap(). Преимущество функции swap() (которая использует ссылки, а не указатели на переменные) заключается гарантии того, что функция в качестве аргументов будет принимать соответствующие типы переменные, а не какую-либо другую информацию, и ссылки будут инициализированы корректно перед их использованием. Это отслеживается компилятором в момент преобразования текста программы в объектный код и выдается сообщение об ошибке, если использование ссылок неверно. В отличие от указателей со ссылками нельзя выполнять следующие операции:

• нельзя получить адрес ссылки, используя оператор адреса C++;
• нельзя присвоить ссылке указатель;
• нельзя сравнить значения ссылок, используя операторы сравнения C++;
• нельзя выполнять арифметические операции над ссылкой, например, добавить смещение;


<< Предыдущая Оглавление Следующая >>