Динамический массив в С++

Динамическое выделение памяти необходимо для эффективного использования памяти компьютера. Например, мы написали какую-то программку, которая обрабатывает массив. При написании данной программы необходимо было объявить массив, то есть задать ему фиксированный размер (к примеру, от 0 до 100 элементов). Тогда данная программа будет не универсальной, ведь может обрабатывать массив размером не более 100 элементов. А если нам понадобятся всего 20 элементов, но в памяти выделится место под 100 элементов, ведь объявление массива было статическим, а такое использование памяти крайне не эффективно.

В С++ операции new и delete предназначены для динамического распределения памяти компьютера.  Операция new  выделяет память из области свободной памяти, а операция delete высвобождает выделенную память.  Выделяемая память, после её использования должна высвобождаться, поэтому операции new и delete используются парами. Даже если не высвобождать память явно, то она освободится ресурсами ОС по завершению работы программы. Рекомендую все-таки не забывать про операцию delete.

// пример использования операции new
int *ptrvalue = new int;
//где ptrvalue – указатель на выделенный участок памяти типа int                   
//new – операция выделения свободной памяти под создаваемый объект.

Операция new создает объект заданного типа, выделяет ему память и возвращает указатель правильного типа на данный участок памяти. Если память невозможно выделить, например, в случае отсутствия свободных участков, то возвращается нулевой указатель, то есть указатель вернет значение 0. Выделение памяти возможно под любой тип данных: intfloat,double, char и т. д.

// пример использования операции delete:
delete ptrvalue;
// где ptrvalue – указатель на выделенный участок памяти типа int                  
// delete – операция высвобождения памяти

Разработаем программу, в которой будет создаваться динамическая переменная.

// new_delete.cpp: определяет точку входа для консольного приложения.

#include "stdafx.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 int *ptrvalue = new int; // динамическое выделение памяти под объект типа int 
 *ptrvalue = 9; // инициализация объекта через указатель
 //int *ptrvalue = new int (9); инициализация может выполнятся сразу при объявлении динамического объекта
 cout << "ptrvalue = " << *ptrvalue << endl;
 delete ptrvalue; // высвобождение памяти 
 system("pause");
return 0;
}

// код Code::Blocks

// код Dev-C++

// new_delete.cpp: определяет точку входа для консольного приложения.

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 int *ptrvalue = new int; // динамическое выделение памяти под объект типа int
 *ptrvalue = 9; // инициализация объекта через указатель
 //int *ptrvalue = new int (9); инициализация может выполнятся сразу при объявлении динамического объекта
 cout << "ptrvalue = " << *ptrvalue << endl;
 delete ptrvalue; // высвобождение памяти
 return 0;
}

В строке 10 показан способ объявления и инициализации девяткой динамического объекта, все, что  нужно так это указать значение в круглых скобочках после типа данных. Результат работы программы показан на рисунке 1.

CppStudio.com
ptrvalue = 9
Для продолжения нажмите любую клавишу . . .

Рисунок 1 — Динамическая переменная

Создание динамических массивов

Как было сказано раньше, массивы также могут быть динамическими. Чаще всего операции new и delete применяются для создания динамических массивов, а не для создания динамических переменных. Рассмотрим фрагмент кода создания одномерного динамического массива.

// объявление одномерного динамического массива на 10 элементов:
float *ptrarray = new float [10];
//  где ptrarray  – указатель на выделенный участок памяти под массив вещественных чисел  типа float 
//      в квадратных скобочках указываем размер массива

После того как динамический массив стал ненужным, нужно освободить участок памяти, который под него выделялся.

// высвобождение памяти отводимой под одномерный динамический массив:
delete [] ptrarray;

После оператора delete ставятся квадратные скобочки, которые говорят о том, что высвобождается участок памяти, отводимый под одномерный массив. Разработаем программу, в которой создадим одномерный динамический массив, заполненный случайными числами.

// new_delete_array.cpp: определяет точку входа для консольного приложения.

#include "stdafx.h"
#include <iostream>
// в заголовочном файле <ctime> содержится прототип функции time()
#include <ctime> 
// в заголовочном файле <iomanip> содержится прототип функции setprecision()
#include <iomanip> 
using namespace std;

int main(int argc, char* argv[])
{
    srand(time(0)); // генерация случайных чисел
    float *ptrarray = new float [10]; // создание динамического массива вещественных чисел на десять элементов
        for (int count = 0; count < 10; count++) 
            ptrarray[count] = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10
        cout << "array = ";
        for (int count = 0; count < 10; count++)
            cout << setprecision(2) << ptrarray[count] << "    ";
        delete [] ptrarray; // высвобождение памяти 
        cout << endl;
    system("pause");
    return 0;
}

// код Code::Blocks

// код Dev-C++

// new_delete_array.cpp: определяет точку входа для консольного приложения.

#include <iostream>
// в заголовочном файле <ctime> содержится прототип функции time()
#include <ctime>
// в заголовочном файле <iomanip> содержится прототип функции setprecision()
#include <iomanip>
#include <cstdlib>
using namespace std;

int main(int argc, char* argv[])
{
    srand(time(0)); // генерация случайных чисел
    float *ptrarray = new float [10]; // создание динамического массива вещественных чисел на десять элементов
        for (int count = 0; count < 10; count++)
            ptrarray[count] = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10
        cout << "array = ";
        for (int count = 0; count < 10; count++)
            cout << setprecision(2) << ptrarray[count] << "    ";
        delete [] ptrarray; // высвобождение памяти
        cout << endl;
    system("pause");
    return 0;
}

Созданный одномерный динамический массив заполняется случайными вещественными числами, полученными c помощью функций генерации случайных чисел, причём числа генерируются в интервале от 1 до 10, интервал задается так — rand() % 10 + 1Чтобы получить случайные вещественные числа, выполняется операция деления, с использованием явного приведения к вещественному типу знаменателя — float((rand() % 10 + 1)). Чтобы показать только два знака после запятой используем функцию setprecision(2)прототип данной функции находится в заголовочном файле <iomanip>Функция time(0) засевает генератор случайных чисел временным значением, таким образом, получается, воспроизводить случайность возникновения чисел (см. Рисунок 2).

CppStudio.com
array = 0.8    0.25    0.86    0.5    2.2    10    1.2    0.33    0.89    3.5

Для продолжения нажмите любую клавишу . . .

Рисунок 2 — Динамический массив в С++

По завершению работы с массивом, он удаляется, таким образом, высвобождается память, отводимая под его хранение.

Как создавать и работать с одномерными динамическими массивами мы научились. Теперь рассмотрим фрагмент кода, в котором показано, как объявляется двумерный динамический массив.

// объявление двумерного динамического массива на 10 элементов:
float **ptrarray = new float* [2]; // две строки в массиве
    for (int count = 0; count < 2; count++)
        ptrarray[count] = new float [5]; // и пять столбцов
//  где ptrarray  – массив указателей на выделенный участок памяти под массив вещественных чисел  типа float

Сначала объявляется указатель второго  порядка float **ptrarray, который ссылается на массив указателей  float* [2], где размер массива равен двумПосле чего в цикле for каждой строке массива объявленного в строке 2 выделяется память под пять элементов. В результате получается двумерный динамический массив  ptrarray[2][5]. Рассмотрим пример высвобождения памяти отводимой под двумерный динамический массив.

// высвобождение памяти отводимой под двумерный динамический массив:
    for (int count = 0; count < 2; count++) 
        delete [] ptrarray[count];
//      где 2 – количество строк в массиве

Объявление и удаление двумерного динамического массива выполняется с помощью цикла, так как показано выше, необходимо понять и  запомнить то, как это делается. Разработаем программу, в которой создадим двумерный динамический массив.

// new_delete_array2.cpp: определяет точку входа для консольного приложения.

#include "stdafx.h"
#include <iostream>
#include <ctime> 
#include <iomanip> 
using namespace std;

int main(int argc, char* argv[])
{
    srand(time(0)); // генерация случайных чисел
    // динамическое создание двумерного массива вещественных чисел на десять элементов
    float **ptrarray = new float* [2]; // две строки в массиве
    for (int count = 0; count < 2; count++)
        ptrarray[count] = new float [5]; // и пять столбцов
    // заполнение массива 
    for (int count_row = 0; count_row < 2; count_row++) 
        for (int count_column = 0; count_column < 5; count_column++) 
            ptrarray[count_row][count_column] = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10
    // вывод массива 
    for (int count_row = 0; count_row < 2; count_row++) 
    {
        for (int count_column = 0; count_column < 5; count_column++) 
            cout << setw(4) <<setprecision(2) << ptrarray[count_row][count_column] << "   ";
        cout << endl;
    }
    // удаление двумерного динамического массива
    for (int count = 0; count < 2; count++) 
        delete []ptrarray[count];
    system("pause");
    return 0;
}

// код Code::Blocks

// код Dev-C++

// new_delete_array2.cpp: определяет точку входа для консольного приложения.

#include <iostream>
#include <ctime>
#include <iomanip>
#include <cstdlib>
using namespace std;

int main(int argc, char* argv[])
{
    srand(time(0)); // генерация случайных чисел
    // динамическое создание двумерного массива вещественных чисел на десять элементов
    float **ptrarray = new float* [2]; // две строки в массиве
    for (int count = 0; count < 2; count++)
        ptrarray[count] = new float [5]; // и пять столбцов
    // заполнение массива
    for (int count_row = 0; count_row < 2; count_row++)
        for (int count_column = 0; count_column < 5; count_column++)
            ptrarray[count_row][count_column] = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10
    // вывод массива
    for (int count_row = 0; count_row < 2; count_row++)
    {
        for (int count_column = 0; count_column < 5; count_column++)
            cout << setw(4) <<setprecision(2) << ptrarray[count_row][count_column] << "   ";
        cout << endl;
    }
    // удаление двумерного динамического массива
    for (int count = 0; count < 2; count++)
        delete []ptrarray[count];
    system("pause");
    return 0;
}

При выводе массива была использована функция setw(), если вы не забыли, то она отводит место заданного размера под выводимые данные. В нашем случае, под каждый элемент массива по четыре позиции, это  позволяет выровнять, по столбцам, числа разной длинны (см. Рисунок 3).

CppStudio.com
 2.7     10   0.33      3    1.4
   6   0.67   0.86    1.2   0.44
Для продолжения нажмите любую клавишу . . .

Рисунок 3 — Динамический массив в С++

Автор: admin
Дата: 25.08.2012
Поделиться:

Комментарии

  1. Никита Абраменко

    А можно ли удалять отдельные элементы массива

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.