Инструменты пользователя

Инструменты сайта


operatory_dinamicheskogo_raspredelenija_pamjati

Различия

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

Ссылка на это сравнение

operatory_dinamicheskogo_raspredelenija_pamjati [2018/12/30 02:33] (текущий)
Строка 1: Строка 1:
 +====== Операторы динамического распределения памяти С++ ======
 +{{htmlmetatags>​
 +metatag-description=(В языке С++ предусмотрены два оператора динамического распределения памяти:​ new и delete.)
 +}}
 +{{ ::​cpp-memory-01.png?​nolink&​400 |}}
 +**Операторы динамического распределения памяти**:​ new(), delete(); malloc(), free().
  
 +В языке С++ предусмотрены два оператора динамического распределения памяти:​ **new** и **delete**. Эти операторы выделяют и освобождают память в ходе выполнения программы. Динамическое распределение памяти представляет собой важную часть практически всех реальных программ. В языке С++ есть альтернативный способ динамического распределения памяти,​ основанный на функциях malloc() и free(). Они сохранены для того, чтобы достичь совместимости с языком С. Однако в программах на языке С++ следует применять операторы new и delete, поскольку они имеют ряд важных преимуществ:​ во-первых,​ оператор new автоматически выделяет количество памяти,​ необходимое объекту указанного типа (оператор [[sizeof]] теперь применять не следует),​ во-вторых,​ оператор new автоматически возвращает указатель заданного типа. Также операторы new и delete можно перегружать,​ что позволяет создавать настраиваемые системы для выделения динамической памяти. <note tip>​Оператор delete следует применять только к результатам оператора new. В противном случае могут возникнуть проблемы,​ например,​ крах операционной системы.</​note>​
 +===== Общее определение операторов new и delete =====
 +Оператор new выделяет область памяти и возвращает указатель на ее первую ячейку. Оператор delete освобождает память,​ выделенную ранее с помощью оператора new.
 +
 +  * //​указатель//​ = **new** //тип// (//​начальное_значение//​);​
 +  * **delete** //​указатель//​
 +  * в случае массива в оператор delete используются скобки []: **delete** [] //​указатель//​
 +<​file>​
 +/* 
 + * File:   
 + * Author: darkfire
 + *
 + * Created on September 15, 2010, 6:32 PM
 + */
 +
 +#include <​iostream>​
 +#include <​ctime>​
 +#include <​stdlib.h>​
 +
 +using namespace std;
 +
 +const int SIZE = 7;
 +
 +int main () {
 +    srand(time(NULL));​
 +    int *parr = new int [SIZE]; // Определили указатель. Выделили память для массива.
 +    int *parr0 = parr; //​сохранили для дальнейшего использования адресс массива.
 +
 +    for (int i=0;​i<​SIZE-1;​i++){
 + *parr=rand()%100;​
 + cout<<​*parr<<"​\n";​
 + parr++;
 +    }
 +    parr = parr0;
 +    ​
 +    for (int i=0;​i<​SIZE-1;​i++){
 +        cout<<​*parr<<"​\n";​
 +        parr++;
 +    }
 +    parr = parr0;/* если указателю не присвоить адресс первого элемента массива
 +                  * оператор делете будет выводить ошибку.
 +    */
 +    delete [] parr;
 +
 +}
 +</​file>​
 +====== Многомерные динамические массивы ======
 +Многомерный массив в C по своей сути одномерен. Операции new и delete позволяют создавать и удалять динамические массивы,​ поддерживая при этом иллюзию произвольной размерности. Деятельность по организации динамического массива требует дополнительного внимания,​ которое окупается важным преимуществом:​ характеристики массива (операнды операции new) могут не быть константными выражениями. Это позволяет создавать многомерные динамические массивы произвольной конфигурации.
 +
 +Следующий пример иллюстрирует работу с динамическими массивами.
 +<​file>​
 +#include <​iostream>​
 +using namespace std;
 + 
 + void main()
 + {
 +  int i, j;
 +
 + // Переменные для описания характеристик массивов.
 + int m1 = 5, m2 = 5;
 +
 + /*
 + Организация двумерного динамического массива производится в два этапа.
 + Сначала создаётся одномерный массив указателей,​ а затем каждому элементу
 +  этого массива присваивается адрес одномерного массива. Для характеристик
 + размеров массивов не требуется константных выражений.
 + */
 + int **pArr = new int*[m1];
 + for (i = 0; i < m1; i++) 
 + pArr[i] = new int[m2];
 +
 + pArr[3][3] = 100;
 + cout << pArr[3][3] << "​\n";​
 +
 + ​ //​Последовательное уничтожение двумерного массива…
 +
 + for (i = 0; i < m1; i++) 
 + delete[]pArr[i];​
 + delete[]pArr;​
 +}
 +</​file>​
 +
 +====== Алгоритм изменения размера динамического массива ======
 +Например,​ мы хотим увеличить размер уже существующего динамического массива на 1.
 +  - Создаем новый динамический массив с размерность на единицу больше от существующего массива.
 +  - Копируем все данные из старого массива в новый массив.
 +  - Добавляем значение нового элемента массива.
 +  - Удаляем старый массив. (Может понадобиться изменить переменную размерности массива,​ например если размерность указывалась через глобальную переменную).
 +  - Присваиваем старому указателю адрес нового массива.
 +
 +====== Примеры на многомерные динамические массивы ======
 +  * Организация двумерного "​треугольного"​ динамического массива.
 +Сначала создаётся одномерный массив указателей,​ а затем каждому элементу этого массива присваивается адрес одномерного массива. При этом размер (количество элементов) каждого нового массива на единицу меньше размера предыдущего. Включённая в квадратные скобки переменная,​ которая является операндом операции new, позволяет легко сделать это. ​
 +
 +<​file>​
 +#include <​iostream>​
 +using namespace std;
 +
 +void main()
 +{
 + int i, j;
 +
 + // Переменные для описания характеристик массивов.
 + int m1 = 5, wm = 5;
 + int **pXArr = new int*[m1];
 +
 + for (i = 0; i < m1; i++, wm--) 
 + pXArr[i] = new int[m1];
 +
 +
 + //​Заполнение массива нулями и показ его на экран
 + for (i = m1 - 1; i >= 0; i--, wm++) {
 + for (j = 0; j < wm; j++){
 + pXArr[i][j]=0;​
 + cout<<​pXArr[i][j]<<"​\t";​
 + }
 + cout<<"​\n\n";​
 + }
 +
 + //​Последовательное уничтожение двумерного массива треугольной конфигурации…
 +
 + for (i = 0; i < m1; i++) 
 + delete[]pXArr[i];​
 + delete[]pXArr;​
 +}
 +</​file>​
 +
 +  * **Организация трехмерного динамического массива.**
 +Создание и уничтожение трёхмерного массива требует дополнительной итерации. Однако здесь также нет ничего принципиально нового.
 +<​file>​
 + #​include <​iostream>​
 +using namespace std;
 +
 +void main()
 +{
 + int i, j;
 +
 + // Переменные для описания характеристик массивов.
 + int m1 = 5, m2 = 5, m3 = 2;
 +
 + // указатель на указатель на указатель :)
 + int ***ppArr;
 +
 + // Создание массива
 + ppArr = new int**[m1];
 + for (i = 0; i <m1; i++) 
 + ppArr[i] = new int*[m2];
 +
 + for (i = 0; i < m1; i++)
 + for (j = 0; j < m2; j++) 
 + ppArr[i][j] = new int[m3];
 +
 + ppArr[1][2][3] = 750; 
 + cout << ppArr[1][2][3] << "​\n"; ​
 +
 + // Удаление в последовательности,​ обратной созданию
 + for (i = 0; i < m1; i++)
 + for (j = 0; j < m2; j++) 
 + delete[]ppArr[i][j];​
 +
 + for (i = 0; i < m1; i++) 
 + delete[]ppArr[i];​
 + delete[] ppArr;
 +}
 +</​file>​
operatory_dinamicheskogo_raspredelenija_pamjati.txt · Последние изменения: 2018/12/30 02:33 (внешнее изменение)