Динамический массив (dynamic array) — массив, созданный в
динамической памяти выражением new T[n]. Его
размер может быть известен только во время работы программы. Освобождается он
через delete[].
Зачем нужно
Размер обычного массива обязан быть константой времени компиляции:
int n = 10;
int a[n]{1, 2, 3}; // стандартом запрещено, но компиляторы позволяют
int* b = new int[n]{1, 2, 3}; // OkGCC с -pedantic выдаёт для первой строки ISO C++ forbids variable length array 'a'. У new[] такого ограничения нет.
Как работает
new T[n] создаёт n элементов подряд и возвращает указатель на
нулевой:
int* array = new int[10];
array[3] = 7; // индексирование работает как у массива
// ...
delete[] array;Память из new[] освобождается только delete[].
Результат — указатель на элемент, а не массив, поэтому sizeof видит указатель:
sizeof(new int[10]) == sizeof(int*); // 8
sizeof(*array) == sizeof(int); // trueЧисло элементов через sizeof не узнать — его хранят в отдельной переменной.
Многомерный динамический массив
Моделируется массивом массивов: массив указателей, каждый из которых указывает на свою строку:
int** array = new int*[n];
for (int i = 0; i < n; ++i) {
array[i] = new int[m];
}
array[i][j]; // как у обычного двумерного
for (int i = 0; i < n; ++i) {
delete[] array[i];
}
delete[] array;Освобождают в обратном порядке: сначала строки, потом массив указателей.
Тонкости
Не из лекции
new int[10]не инициализирует элементы,new int[10]()иnew int[10]{}заполняют нулями.- Если инициализаторов больше, чем
n,new int[n]{1, 2, 3}бросаетstd::bad_array_new_length(GCC 16.2,n == 2).deleteвместоdelete[]— неопределённое поведение. GCC предупреждает (-Wmismatched-new-delete), AddressSanitizer сообщаетalloc-dealloc-mismatch.- Строки массива массивов лежат в разных местах памяти, а не подряд, как у
int[n][m].
Частые ошибки
delete array;вместоdelete[] array;.- Удалить
arrayраньше строк — указатели на строки теряются, утечка. - Пытаться узнать длину через
sizeof(array) / sizeof(int). - Читать элементы
new int[n]до записи.