Динамически распределенный массив C++
Массивы — это очень важная структура данных в C ++, которая служит для хранения схожих типов элементов. Массивы в основном делятся на два разных типа: статические и динамические. Статические массивы — это те, размер которых предварительно определен в коде, тогда как динамические массивы — это те, размер которых определяется во время выполнения. В этой статье мы подробно поговорим о динамических массивах в C ++. Более того, мы уделим особое внимание их распределению и освобождению, поделившись с вами подробным примером в Ubuntu 20.04.
Содержание
- Динамически размещаемые массивы в C ++
- Использование динамически размещаемых массивов в C ++ в Ubuntu 20.04
- Заключение
Динамически размещаемые массивы в C ++
Мы уже заявляли, что размер динамического массива определяется во время выполнения. Однако может возникнуть вопрос, зачем нам вообще нужны динамически выделяемые массивы, когда мы можем удобно использовать статические массивы? Что ж, иногда вы сталкиваетесь с такими ситуациями, когда размер массива изначально неизвестен.
В этих случаях вы можете получить размер массива как ввод от пользователя во время выполнения.
Но это невозможно со статическими массивами, поскольку размер статического массива, однажды определенного в коде, не может быть изменен. Здесь в игру вступают динамически выделяемые массивы, которые могут определять массивы любого желаемого размера во время выполнения. Динамические массивы в C ++ можно легко создать с помощью ключевого слова «new». Точный синтаксис будет пояснен позже в этой статье.
Однако здесь следует отметить важный момент: статические массивы всегда создаются в стеке вашей системы, и ваша система сама берет на себя ответственность за освобождение своего стека после завершения вашей программы. С другой стороны, динамически выделяемые массивы всегда создаются в куче, и вам нужно вручную освобождать память, занимаемую динамическим массивом. Теперь вам нужно увидеть пример, обсуждаемый ниже, чтобы понять использование динамически выделяемых массивов.
Использование динамически размещаемых массивов в C ++ в Ubuntu 20.
04В этом примере мы хотим научить вас использовать динамически выделяемые массивы в C ++. Мы расскажем, как можно объявить и инициализировать динамический массив во время выполнения. Затем мы отобразим элементы динамически выделяемого массива. Наконец, мы покажем вам, как можно освободить память, занимаемую динамическим массивом в C ++. Чтобы узнать все это, вам нужно будет увидеть код, показанный на следующем изображении:
В этой программе на C ++ у нас есть функция main (), в которой мы определили целое число num. Это целое число будет соответствовать размеру нашего динамического массива, который мы создадим позже. Затем мы отобразили на терминале сообщение, предлагающее пользователю ввести любой размер по своему выбору для динамического массива. После этого мы взяли этот размер в качестве ввода от пользователя. Затем с помощью оператора «int * array = new int (num)» мы объявили динамический массив во время выполнения, размер которого равен переменной «num». «Массив» относится к имени этого массива.
После этого мы снова отобразили на терминале сообщение, предлагающее пользователю ввести элементы этого массива. За этим сообщением следует цикл for, который повторяется до размера массива, т.е. num. В этом цикле мы взяли элементы этого динамического массива в качестве входных данных от пользователя.
После того, как динамический массив был заполнен, мы хотели отобразить его элементы на терминале, для которого мы сначала отобразили сообщение с помощью оператора «cout». Затем у нас есть еще один цикл for, который снова перебирает размер динамического массива. В этом цикле мы просто отобразили элементы массива на терминале. После этого мы хотели освободить память, занятую этим динамическим массивом, для которого мы использовали оператор «delete [] array». Наконец, на всякий случай мы использовали оператор «array = NULL», чтобы также удалить ссылку NULL динамического массива, память которого мы только что освободили.
После написания этого кода, когда мы его скомпилировали и выполнили, нас сначала попросили ввести размер динамического массива.
Мы хотели, чтобы наш динамический массив имел размер «5», как показано на изображении ниже:
Как только мы ввели размер нашего динамического массива, нас попросили заполнить его. Для этого мы ввели числа от 1 до 5, как показано на следующем изображении:
Как только мы нажали клавишу Enter после заполнения нашего динамического массива, его элементы были напечатаны на терминале. Кроме того, также произошло освобождение динамической памяти, из-за чего уведомление об этом также появилось на терминале, как показано на изображении ниже:
Теперь мы немного подправим тот же код. До сих пор мы узнали, как можно инициализировать динамический массив в C ++ и отображать его элементы на терминале. Хотя мы также включили в нашу программу код для освобождения этой памяти, тем не менее, мы все еще не уверены, была ли освобождена занятая динамическая память успешно или нет. Для этого мы попытаемся получить доступ к части этой динамической памяти после ее освобождения.
Если доступ к нему осуществлен успешно, это будет означать, что освобождение памяти не произошло правильно.
Однако, если мы встретим какое-либо сообщение об ошибке при доступе к этой памяти после ее освобождения, это будет означать, что наша занятая динамическая память теперь успешно освобождена. Чтобы понять это, вам нужно взглянуть на следующий модифицированный код:
В этом модифицированном коде C ++ мы просто добавили строку в конец нашей программы, то есть cout << array [2]. Это означает, что мы хотим получить доступ к третьему индексу нашего динамического массива после освобождения занимаемой им памяти.
Когда мы скомпилировали и выполнили этот код, он работал отлично, однако, как только эта последняя строка была выполнена, была сгенерирована ошибка, относящаяся к ошибке сегментации, что на самом деле означает, что вы пытаетесь получить доступ к области памяти, которая больше не существует.. Это показано на прикрепленном изображении.
Это означает, что освобождение нашего динамического массива прошло успешно.
Этот вывод также подразумевает, что попытка доступа к области памяти, которая больше не существует, приводит только к ошибке времени выполнения, а не к ошибке компиляции. Это означает, что такой код всегда будет успешно компилироваться, и вы не сможете отловить такую ошибку, пока не запустите свой код.
Заключение
Эта статья была нацелена на то, чтобы научить вас использовать динамически выделяемые массивы в C ++ в Ubuntu 20.04. Для этого мы сначала подчеркнули необходимость использования динамически выделяемых массивов в C ++. Затем мы рассмотрели подробный пример, объясняющий, как создавать динамические массивы и работать с ними в C ++. Более того, мы также поделились методом освобождения динамических массивов. Изучив это руководство, вы обязательно получите базовое представление о работе с динамическими массивами в C ++.
Динамическое выделение памяти в C++ для 2D и 3D массива
В этом посте будет обсуждаться динамическое выделение памяти в C++ для многомерных массивов.
1. Одномерный массив
Ниже приведен простой пример, демонстрирующий динамическое выделение памяти в одномерных массивах.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <iostream>
#define N 10
// Динамическое выделение памяти для одномерного массива в C++ int main() { // динамически выделяем память размером `N` int* A = new int[N];
// присваиваем значения выделенной памяти for (int i = 0; i < N; i++) { A[i] = i + 1; }
// печатаем одномерный массив for (int i = 0; i < N; i++) { std::cout << A[i] << » «; // или *(А + i) }
// освобождаем память delete[] A;
return 0; } |
Скачать Выполнить код
2.
Двумерный массив1. Использование одного указателя
В этом подходе мы просто выделяем один большой блок памяти размером M × N динамически и присвоить его указателю. Затем мы можем использовать арифметику указателя для индексации двумерного массива.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream>
// Матрица `M × N` #define M 4 #define N 5
// Динамическое выделение памяти для 2D-массива в C++ int main() { // динамически выделяем память размером `M × N` int* A = new int[M * N];
// присваиваем значения выделенной памяти for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { *(A + i*N + j) = rand() % 100; } }
// печатаем двумерный массив for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { std::cout << *(A + i*N + j) << » «; // или (A + i*N)[j]) } std::cout << std::endl; }
// освобождаем память delete[] A;
return 0; } |
Скачать Выполнить код
2.
Использование массива указателейМы можем динамически создать массив указателей размером M а затем динамически выделять память размером N для каждой строки, как показано ниже:
1 2 3 4 5 6 7 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <iostream>
// Матрица `M × N` #define M 4 #define N 5
// Динамическое выделение памяти в C++ для 2D-массива int main() { // динамически создать массив указателей размера `M` int** A = new int*[M];
// динамически выделяем память размером `N` для каждой строки for (int i = 0; i < M; i++) { A[i] = new int[N]; }
// присваиваем значения выделенной памяти for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { A[i][j] = rand() % 100; } }
// печатаем двумерный массив for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { std::cout << A[i][j] << » «; } std::cout << std::endl; }
// освобождаем память с помощью оператора удаления for (int i = 0; i < M; i++) { delete[] A[i]; } delete[] A;
return 0; } |
Скачать Выполнить код
3.
Трехмерный массив1. Использование одного указателя
Как видно для двумерного массива, мы выделяем память размером X × Y × Z динамически и назначить его указателю. Затем мы используем арифметику указателя для индексации трехмерного массива.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <iostream>
// Матрица `X × Y × Z` #define X 2 #define Y 3 #define Z 4
// Динамическое выделение памяти в C++ для 3D-массива int main() { // динамически выделяем память размером `X × Y × Z` int* A = new int[X * Y * Z];
// присваиваем значения выделенной памяти for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { for (int k = 0; k < Z; k++) { *(A + i*Y*Z + j*Z + k) = rand() % 100; } } }
// печатаем трехмерный массив for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { for (int k = 0; k < Z; k++) { std::cout << *(A + i*Y*Z + j*Z + k) << » «; } std::cout << std::endl; } std::cout << std::endl; }
// освобождаем память delete[] A;
return 0; } |
Скачать Выполнить код
2.
Использование тройного указателя1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <iostream>
// Матрица `X × Y × Z` #define X 2 #define Y 3 #define Z 4
// Динамическое выделение памяти для 3D-массива в C++ int main() { int*** A = new int**[X];
for (int i = 0; i < X; i++) { A[i] = new int*[Y]; for (int j = 0; j < Y; j++) { A[i][j] = new int[Z]; } }
// присваиваем значения выделенной памяти for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { for (int k = 0; k < Z; k++) { A[i][j][k] = rand() % 100; } } }
// печатаем трехмерный массив for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { for (int k = 0; k < Z; k++) { std::cout << A[i][j][k] << » «; } std::cout << std::endl; } std::cout << std::endl; }
// освобождаем память for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { delete[] A[i][j]; } delete[] A[i]; }
delete[] A;
return 0; } |
Скачать Выполнить код
Вот и все, что касается динамического выделения памяти в C++ для 2D- и 3D-массивов.
Оценить этот пост
Средний рейтинг 4.9/5. Подсчет голосов: 48
Голосов пока нет! Будьте первым, кто оценит этот пост.
Сожалеем, что этот пост не оказался для вас полезным!
Расскажите, как мы можем улучшить этот пост?
Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.
Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂
Динамическое размещение
Динамическое размещениеВыделение памяти
Существует два способа выделения памяти для хранения данных:- Время компиляции (или статическое) Распределение
- Память для именованных переменных выделяется компилятором
- Точный размер и тип хранилища должны быть известны во время компиляции
- Вот почему для стандартных объявлений массива размер должен быть константа
- Динамическое выделение памяти
- Память выделяется «на лету» во время выполнения
- динамически выделяемое пространство, обычно размещаемое в известном программном сегменте как куча или свободное хранилище
- Необязательно знать точное количество места или количество элементов.
компилятором заранее. - Для динамического выделения памяти указатели имеют решающее значение
Динамическое выделение памяти
- Мы можем динамически выделять место для хранения, пока программа работает, но мы не можем создавать новые имена переменных «на лету»
- По этой причине динамическое размещение требует двух шагов:
- Создание динамического пространства.
- Сохранение своего адреса в указателе (чтобы место можно получить)
- Для динамического выделения памяти в C++ мы используем новый . оператор.
- Освобождение:
- Освобождение — это «очистка» пространства, используемого для переменных или другое хранилище данных
- Переменные времени компиляции автоматически освобождаются на основе их известная степень (это то же самое, что и область действия для «автоматического» переменные)
- Освобождение динамически созданных пробел
- Чтобы освободить динамическую память, мы используем удаление оператор
Выделение места с новым
- Для динамического распределения пространства используйте унарный оператор новый , за которым следует тип .

новый интервал; // динамически выделяет int новый двойник; // динамически выделяет двойной
- При динамическом создании массива используйте ту же форму, но расставьте скобки
с размером после типа:
новый интервал [40]; // динамически выделяет массив из 40 целых чисел новый двойной [размер]; // динамически выделяет массив двойников размера // обратите внимание, что размер может быть переменной - Эти заявления выше сами по себе не очень полезны, потому что
выделенные пространства не имеют имен! НО, новый оператор возвращает
начальный адрес выделенного пространства, и этот адрес может быть
хранится в указателе:
интервал * р; // объявить указатель p р = новый интервал; // динамически выделяем int и загружаем адрес в p двойной * д; // объявить указатель d д = новый двойной; // динамически выделяем двойник и загружаем адрес в d // мы также можем сделать это в однострочных операторах инт х = 40; int * list = новый int[x]; поплавок * числа = новый поплавок[x+10];
Обратите внимание, что это еще один способ инициализации указателя на верная цель (и самая важная).
Доступ к динамически созданному пространству
- Итак, как только пространство было динамически выделено, как мы можем использовать это?
- Для одиночных предметов переходим по указателю. Разыменовать указатель
для достижения динамически созданной цели:
int * p = новый интервал; // динамическое целое, на которое указывает p *р = 10; // присваивает 10 динамическому целому числу cout
- Для динамически создаваемых массивов можно использовать либо смещение указателя,
нотации или обработайте указатель как имя массива и используйте стандартную
обозначение в скобках:
double * numList = новый двойной [размер]; // динамический массив для (целое я = 0; я
Освобождение динамической памяти
- Чтобы освободить память, созданную с помощью new, мы используем
унарный оператор удалить . Один операнд должен быть указателем
в котором хранится адрес освобождаемого пространства:
int * ptr = новый интервал; // динамически созданный int // .
Обратите внимание, что указатель ptr все еще существует в этом примере. Это именованная переменная, область действия и степень которой определяются при компиляции. время. Его можно использовать повторно:
..
удалить указатель; // удаляет пробел, на который указывает ptr
ptr = новый интервал [10]; // указываем p на новый массив
- Чтобы освободить динамический массив, используйте эту форму:
удалить [] name_of_pointer ;
Пример:int * список = новый int[40]; // динамический массив удалить [] список; // освобождает массив список = 0; // сбрасываем список на нулевой указатель
После освобождения места всегда полезно сбросить указатель на null, если вы не указываете его на другую допустимую цель справа прочь. - На рассмотрение: Итак, что произойдет, если вы не сможете освободить динамическое памяти, когда вы закончили с ним? (т.е. почему освобождение важно?)
Пример приложения: динамическое изменение размера массива
Если у вас есть существующий массив, и вы хотите увеличить его (добавить массив ячеек к нему), вы не можете просто добавлять новые ячейки к старым.
Помните, что массивы хранятся в последовательной памяти, и вы никогда не знаете,
выделена ли память сразу после массива
для чего-то еще. По этой причине процесс занимает еще несколько
шаги. Вот пример использования целочисленного массива. скажем
это исходный массив:int * список = новый int[размер];
Я хочу изменить размер так, чтобы в массиве с именем list было место
еще на 5 номеров (предположительно, потому что старый переполнен).
Есть четыре основных шага.
- Создать совершенно новый массив соответствующего типа и
новый размер. (Для этого вам понадобится еще один указатель).
int * temp = новый int[размер + 5];
- Скопируйте данные из старого массива в новый массив (сохранив
их на одних и тех же позициях). Это легко сделать с помощью цикла for.
для (целое я = 0; я
- Удалите старый массив — он вам больше не нужен! (Делать
как говорит твоя Мама и вынеси мусор!)
удалить [] список; // это удаляет массив, на который указывает «список»
- Изменить указатель.
Вы все еще хотите, чтобы массив вызывался
«список» (его исходное имя), поэтому измените указатель списка на новый адрес.список = темп;
Вот оно! Массив списка теперь на 5 больше, чем предыдущий, и в нем те же данные, что и в исходном. Но сейчас в нем есть место для еще 5 предметов.
Могу ли я создать динамический массив на языке C?
19.01.2016 #1
Я думаю, что нет, потому что невозможно увеличить уже определенную длину массива. Например, если я определяюКод:
int t[10];и позже мне нужно 11 номеров в массиве, мне пришлось бы создать новый:Код:
инт б[11];и скопируйте предыдущие 10 значений из a[] в b[].Но сегодня на другом форуме я прочитал, что в C возможны динамические массивы.
Так что из этого верно?
19.01.2016 #2
«Динамическое выделение памяти»: достигается в C с помощью malloc(), calloc(), realloc() и free().Вам нужно будет включить «stdlib.h», чтобы использовать функции.
Вам следует изучить хорошую книгу по языку программирования C, чтобы понять, как использовать эти функции.
«Автоматические массивы переменной длины разрешены в ISO C99…», но это не соответствует приведенному вами примеру. Опять же, вам нужно изучить документацию вашего компилятора, чтобы узнать, поддерживает ли он стандарт C99, и получить дополнительную информацию о том, как их использовать.
19.01.2016 #3
Вы не можете создать массив с автоматическим изменением размера в C. С++ имеет эту функцию в форме std::vector. Вы можете иметь «динамические» массивы в C, начиная с C99. Но они не динамичны, как вы думаете. Они просто имеют размер, который определяется во время выполнения, а не во время компиляции.
Что это за странное устройство?
Когда я прикасаюсь к нему, он издает звук
.У него есть провода, которые вибрируют и издают музыку
Что это может быть за вещь, которую я нашел?
19.01.2016 #4
Нединамический массивКод:
int x[10]Вы должны узнать размер путем компиляциипсевдодинамического массива
Код:
int *x = malloc(sizeof(int) * y)Вы должен знать размер, запустив (y должен быть где-то определен)Динамический «объект»: связанный список. Читайте о структурах и указателях на структуры. Там лежит ответ на ваш вопрос.
19.01.2016 #5
Первоначально написал Elkvis
… Но они не динамичны в том смысле, как вы думаете …
Википедия говорит:Первоначально написал Википедия
В компьютерных науках динамический массив, расширяемый массив, массив с изменяемым размером, динамическая таблица, изменяемый массив или список массивов — это структура данных списка переменного размера с произвольным доступом, которая позволяет использовать элементы быть добавлены или удалены.
подробнее: https://en.wikipedia.org/wiki/Dynamic_arrayОн поставляется со стандартными библиотеками на многих современных основных языках программирования.
Я знаю, как добавить один элемент в массив в Javascript, там это просто. (Метод push() массива JavaScript)
@rstanley : malloc(), calloc(), realloc() и free() по-прежнему остаются проблемой для меня в C. Насколько это может помочь мне создать динамический массив на C, соответствующий определению, которое я упомянул в цитате из вики. Это действительно динамично или просто соответствует какой-то части определения Википедии?
Последний раз редактировалось nerio; 19.01.2016 в 14:11.
19.01.2016 #6
Первоначально Послано nerio
Википедия говорит:
подробнее: https://en.wikipedia.org/wiki/Dynamic_array
Я знаю, как добавить один элемент в массив в Javascript, там это просто.
( Метод JavaScript Array push() )
@rstanley : malloc(), calloc(), realloc() и free() все еще проблема для изучения в C. Насколько это может помочь мне создать динамический массив в C, что соответствует определению, которое я упомянул в цитате из вики. Это действительно динамично или просто соответствует какой-то части определения Википедии?
Без написания кода для вас:Используйте malloc() для выделения массива из не менее 10 элементов в куче (куча: пространство памяти, выделенное для программы, но еще не используемое). Вы должны выделить место для дополнительных элементов, если вы думаете, что вам нужно будет расширить позже. Массив из 10 элементов довольно минимален.
Если вам нужно расширить массив позже, чтобы вместить больше данных, используйте realloc().
Когда вы закончите работу с пространством данных, вызовите функцию free(), чтобы вернуть выделенное пространство памяти в кучу для потенциального повторного использования какой-либо другой частью программы.

Вам нужно будет включить «stdlib.h», чтобы использовать функции.
У него есть провода, которые вибрируют и издают музыку
Он поставляется со стандартными библиотеками на многих современных основных языках программирования.
( Метод JavaScript Array push() )