Инициализация элементов в динамическом массиве по умолчанию и как её избежать
Суть моего вопроса связана с тем, что при выделении динамического массива примитивных типов в C++ его значения по умолчанию инициализируются нулевыми, например:
int* array = new int[size];
создаст динамический массив из size нулей.
Есть несколько вопросов:
- Гарантирует ли стандарт C++ инициализацию элементов динамически выделенного массива нулями при использовании оператора
new[]без явных инициализаторов? - Тратит ли программа в различных реализациях выделения динамического массива время на инициализацию элементов нулями?
- Есть ли способ выделения динамического массива в C++, который позволяет избежать затрат времени на инициализацию, если мне важна максимальная производительность и я планирую немедленно перезаписать все элементы массива?
Ответы (1 шт):
В массиве по стандарту мусор. В конкретной реализации там могут оказаться нули потому что:
нули могут там быть случайно, как побочный результат работы менеджера кучи или как старые данные;
в отладочном режиме выделяемые блоки могут быть залиты нулями, в релизе такого быть не должно;
в отладочном режиме сегмент памяти под кучу залит нулями;
когда процесс получает память от операционной системы, страница залита нулями (защита данных).
Чтобы все эти причины не влияли, нужно собрать релиз и запустить код, который будет использовать память из кучи многократно. Например так:
#include <iostream>
int main() {
for (int n = 0; ; ++n) {
std::cout << n << '\n';
int *a = new int[n];
for (int i = 0; i < n; ++i) {
if (a[i] != 0) {
std::cout << "garbage\n";
return 0;
}
a[i] = i;
}
delete[] a;
}
}
$ g++ -std=c++17 -pedantic -Wall -Wextra -Werror -Wwrite-strings -Wconversion temp.cpp $ ./a.out 0 1 2 3 4 garbage
P.S. В этой программе есть неопределённое поведение. Так и должно быть - ищем мусор в неинициализованных данных.