Литмир - Электронная Библиотека
A
A

17.3.1. Оператор sizeof

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Итак, сколько памяти требуется для хранения типа
int
? А указателя? Ответы на эти вопросы дает оператор
sizeof
.

cout << "размер типа char" << sizeof(char) << ' '

     << sizeof ('a') << '\n';

cout << "размер типа int" << sizeof(int) << ' '

     << sizeof (2+2) << '\n';

int* p = 0;

cout << "размер типа int*" << sizeof(int*) << ' '

     << sizeof (p) << '\n';

Как видим, можно применить оператор

sizeof
как к имени типа, так и к выражению; для типа оператор
sizeof
возвращает размер объекта данного типа, а для выражения — размер типа его результата. Результатом оператора
sizeof
является положительное целое число, а единицей измерения объема памяти является значение
sizeof(char)
, которое по определению равно
1
. Как правило, тип
char
занимает один байт, поэтому оператор
sizeof
возвращает количество байтов.

ПОПРОБУЙТЕ

Выполните код, приведенный выше, и посмотрите на результаты. Затем расширьте этот пример для определения размера типов

bool
,
double
и некоторых других.

Размер одного и того же типа в разных реализациях языка С++ не обязательно совпадает. В настоящее время выражение

sizeof(int)
в настольных компьютерах и ноутбуках обычно равно четырем. Поскольку в байте содержится 8 бит, это значит, что тип
int
занимает 32 бита. Однако в процессорах встроенных систем тип
int
занимает 16 бит, а в высокопроизводительных архитектурах размер типа
int
обычно равен 64 битам.

Сколько памяти занимает объект класса vector? Попробуем выяснить.

vector<int> v(1000);

cout << "Размер объекта типа vector<int>(1000) = "

     << sizeof (v) << '\n';

Результат может выглядеть так:

Размер объекта типа vector<int>(1000) = 20

Причины этого факта станут очевидными по мере чтения этой и следующей глав (а также раздела 19.2.1), но уже сейчас ясно, что оператор

sizeof
не просто пересчитывает элементы.

17.4. Свободная память и указатели

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Рассмотрим реализацию класса
vector
, приведенную в конце раздела 17.2. Где класс
vector
находит место для хранения своих элементов? Как установить указатель
elem
так, чтобы он ссылался на них? Когда начинается выполнение программы, написанной на языке С++, компилятор резервирует память для ее кода (иногда эту память называют кодовой (code storage), или текстовой (text storage)) и глобальных переменных (эту память называют статической (static storage)). Кроме того, он выделяет память, которая будет использоваться при вызове функций для хранения их аргументов и локальных переменных (эта память называется стековой (stack storage), или автоматической (automatic storage)). Остальная память компьютера может использоваться для других целей; она называется свободной (free). Это распределение памяти можно проиллюстрировать следующим образом.

Программирование. Принципы и практика использования C++ Исправленное издание - _187.png

Язык С++ делает эту свободную память (которую также называют кучей (heap)) доступной с помощью оператора

new
. Рассмотрим пример.

double* p = new double[4]; // размещаем 4 числа double в свободной

                           // памяти

Указанная выше инструкция просит систему выполнения программы разместить четыре числа типа

double
в свободной памяти и вернуть указатель на первое из них. Этот указатель используется для инициализации переменной
p
. Схематически это выглядит следующим образом.

Программирование. Принципы и практика использования C++ Исправленное издание - _188.png

Оператор

new
возвращает указатель на объект, который он создал. Если оператор
new
создал несколько объектов (массив), то он возвращает указатель на первый из этих массивов. Если этот объект имеет тип
X
, то указатель, возвращаемый оператором
new
, имеет тип
X*
. Рассмотрим пример.

char* q = new double[4]; // ошибка: указатель double*

                         // присваивается char*

Данный оператор new возвращает указатель на переменную типа

double
, но тип
double
отличается от типа
char
, поэтому мы не должны (и не можем) присвоить указатель на переменную типа
double
указателю на переменную типа
char
.

17.4.1. Размещение в свободной памяти

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Оператор
new
выполняет выделение (allocation) свободной памяти (free store).

• Оператор

new
возвращает указатель на выделенную память.

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

• Указатель ссылается на объект указанного типа.

• Указатель не знает, на какое количество элементов он ссылается.

Оператор

new
может выделять память как для отдельных элементов, так и для последовательности элементов. Рассмотрим пример.

223
{"b":"847443","o":1}