2.2. Динамическое выделение памяти и указателиПрежде чем углубиться в объектно-ориентированную разработку, нам придется сделать
небольшое отступление о работе с памятью в программе на С++. Мы не сможем написать
сколько-нибудь сложную программу, не умея выделять память во время выполнения
и обращаться к ней. int ival = 1024; заставляет компилятор выделить в памяти область, достаточную для хранения переменной
типа int, связать с этой областью имя ival и поместить туда значение 1024. Все
это делается на этапе компиляции, до выполнения программы. int ival2 = ival + 1; то обращаемся к значению, содержащемуся в переменной ival: прибавляем к нему
1 и инициализируем переменную ival2 этим новым значением, 1025. Каким же образом
обратиться к адресу, по которому размещена переменная? int *pint; // указатель на объект типа int Существует также специальная операция взятия адреса, обозначаемая символом &. Ее результатом является адрес объекта. Следующий оператор присваивает указателю pint адрес переменной ival: int *pint; pint = &ival; // pint получает значение адреса ival Мы можем обратиться к тому объекту, адрес которого содержит pint (ival в нашем случае), используя операцию разыменования, называемую также косвенной адресацией. Эта операция обозначается символом *. Вот как можно косвенно прибавить единицу к ival, используя ее адрес: *pint = *pint + 1; // неявно увеличивает ival Это выражение производит в точности те же действия, что и ival = ival + 1; // явно увеличивает ival В этом примере нет никакого реального смысла: использование указателя для косвенной
манипуляции переменной ival менее эффективно и менее наглядно. Мы привели этот
пример только для того, чтобы дать самое начальное представление об указателях.
В реальности указатели используют чаще всего для манипуляций с динамически размещенными
объектами.
Оператор new имеет две формы. Первая форма выделяет память под единичный объект определенного типа: int *pint = new int(1024); Здесь оператор new выделяет память под безымянный объект типа int, инициализирует
его значением 1024 и возвращает адрес созданного объекта. Этот адрес используется
для инициализации указателя pint. Все действия над таким безымянным объектом
производятся путем разыменовывания данного указателя, т.к. явно манипулировать
динамическим объектом невозможно. int *pia = new int[4]; В этом примере память выделяется под массив из четырех элементов типа int.
К сожалению, данная форма оператора new не позволяет инициализировать элементы
массива. // освобождение единичного объекта delete pint; // освобождение массива delete[] pia; Что случится, если мы забудем освободить выделенную память? Память будет расходоваться
впустую, она окажется неиспользуемой, однако возвратить ее системе нельзя, поскольку
у нас нет указателя на нее. Такое явление получило специальное название утечка
памяти. В конце концов программа аварийно завершится из-за нехватки памяти
(если, конечно, она будет работать достаточно долго). Небольшая утечка трудно
поддается обнаружению, но существуют утилиты, помогающие это сделать. Упражнение 2.3Объясните разницу между четырьмя объектами: (a) int ival = 1024; (b) int *pi = &ival; (c) int *pi2 = new int(1024); (d) int *pi3 = new int[1024]; Упражнение 2.4Что делает следующий фрагмент кода? В чем состоит логическая ошибка? (Отметим, что операция взятия индекса ([]) правильно применена к указателю pia. Объяснение этому факту можно найти в разделе 3.9.2.) int *pi = new int(10); int *pia = new int[10];Назад Вперед Содержание |
2019-08-14 22:45:02 Евгений Хорошая статья 2019-12-12 13:53:31 Инкогнито в примере 2.3: (а) это статическое выделение памяти под переменную. (b) - динамическое выделение памяти(ДВП) и присваивание адреса переменной ival указателю pi. (с) - ДВП для переменной 1024. (d) - ДВП для 1024 элементов массива. 2019-12-12 14:00:15 Инкогнито В примере 2.4: указатель pi = 10, соответственно цикл while не будет запускаться. Но даже если бы он запустился, то это выдало бы ошибку компилятора. Потому что pia[*pi] = *pi - это попытка обратиться к несуществующему элементу массива (pia[10]), тогда как элементов в массиве pia[0 - 9] Оставить комментарий: |