Какова цель "{}" в "новом int [5] {};"?

Если мы напишем что-то вроде:

int *arr = new int[5];

В этом случае система динамически выделяет пространство для 5 элементов типа int и возвращает указатель на первый элемент последовательности.

Но, как только я увидел следующий код:

int *arr = new int[5]{};

Итак, что означает {} после new оператора? Какова цель {} в этом коде?

Я инициализировал массив с моим собственным значением, например:

#include <iostream>

int main()
{
    int* a = new int[5]{1};
    for(int i = 0; i < 5; i++)
        std::cout<< a[i]<<' ';

    delete[] a;
}

Вывод:

1 0 0 0 0

Только первый элемент печати 1. Почему?

Ответ 1

int *arr = new int[5];

выполняет инициализацию по умолчанию (что в этом случае означает, что элементы arr неинициализированы), а

int *arr = new int[5]{};

является инициализацией значения (которая в этом случае означает, что элементы arr инициализируются нулем). См. Соответствующие правила в ссылках. В частности, для последнего случая массив будет инициализирован нулем.

В любом случае, если нет других веских оснований, рекомендуется использовать std::vector.

Изменить: Что касается вашего второго вопроса: Это связано с правилами инициализации. Вам нужно написать

int* a = new int[5]{1, 1, 1, 1, 1 };

Рекомендуемый std::vector поддерживает желаемый синтаксис:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a(5, 1);
    for(int i = 0; i < 5; i++)
        std::cout<< a[i]<<' ';
}

https://ideone.com/yhgyJg Обратите внимание, однако, что здесь используется(). Поскольку у вектора есть конструктор для std:: initializer_list, вызывающий вектор {5, 1} налагает определенную двусмысленность, которая разрешается, всегда предпочитая конструктор initializer_list для {} -инициализации, если это предусмотрено. Поэтому использование {} приведет к созданию вектора с 2 элементами значений 5 и 1, а не 5 элементов значения 1.

Ответ 2

Если вы можете определить разницу между

int a[5];

и

int a[5] = {0};

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

Помимо решения std::vector, наиболее прямое (и общее) решение, отличное от STL, выполняется через массив за один раз:

for (int i = 0; i < sizeof(a)/sizeof(int); i ++)
    a[i] = 1;

FYI, используя инициализацию списка, приводит к тому, что все неуказанные элементы массива устанавливаются равными нулю, например

int a[5] = {[1] = 3};
// Now a is {0, 3, 0, 0, 0}