Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Итог_Пособие C++.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.03 Mб
Скачать

2.1.2 Способы динамического выделения и освобождения памяти

В С++ имеется два способа работы с динамической памятью:

• использование операций new и delete (основной способ, принятый в С++)

• использование функций malloc (calloc, realloc) и free (способ, доставшийся в наследство от языка С).

Первым способом мы уже пользовались в предыдущей главе для динамического формирования массивов (раздел 1.). Напомним, что операция new выделяет память в динамической области для переменной, исходя из её типа, и возвращает указатель на эту переменную (при захвате памяти под массив обязательно нужно указать количество элементов массива). Операция delete выполняет противоположное действие – она освобождает память, которую занимала переменная, т.е. делает эту область памяти доступной для захвата другими переменными. Для того, чтобы освободить всю память, которая захватывалась под массив, используется синтаксис delete[].

В качестве примера использования операций new и delete на этот раз покажем один из вариантов динамического формирования двумерного массива (матрицы из n строк и m столбцов).

// Пример 2.1 Динамическое формирование двумерного массива

#include <iostream>

using namespace std;

int main()

{

int n, m;

cout<<"n=7"; cin>>n;

int **c=new int*[n]; //сформировали массив указателей на строки

cout<< "m=? "; cin >> m;

for(int i=0;i<n;i++) {

c[i]=new int[m]; // а тут выделяем память для каждой строки

for (int j=0; j<m;j++){

c[i][j]=i+j; // как-то заполняем матрицу значениями

cout.width(4); cout<<c[i][j];

} cout<<endl;

} //пусть матрица больше не нужна - освободим память

for(int i=0;i<n;i++) delete[] c[i];

//освободили память, которую занимал массив указателей

delete[] c;

system("pause");

return 0;

}

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

Особенности использования функций malloc, calloc и realloc заключаются в следующем:

  • размер захватываемой области памяти явно задаётся в байтах, для вычисления размера, исходя из типа, обычно используется операция sizeof

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

Например, для того, чтобы выделить память под массив из n элементов типа double (предполагаем, что значение n ранее было задано в программе), можно использовать функцию malloc или функцию calloc:

double *t=(double *)malloc(n*sizeof(double));

double *t=(double *)calloc(n, sizeof(double));

А чтобы увеличить размер памяти для массива в два раза, можно воспользоваться функцией realloc

double *t=(double *)realloc(t, 2*n*sizeof(double));

Очевидно, синтаксис функций из примеров понятен – не очень удобно, но можно привыкнуть. Добавим только, что если в функции realloc указатель t изначально имеет значение NULL, она выполняется как malloc.

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

free(t);

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]