new int[100]和new int[100]()的区别是什么?

3
作为标题
#include <iostream>
int main() {
    auto* a = new float[1000000];
    auto* b = new float[10]();
    for(auto i=0; i<1000000; i++){
        std::cout << "a" << a[i] << std::endl;
    }
    for(auto i=0; i<10; i++){
        std::cout << "b" << b[i] << std::endl;
    }
    return 0;
}

有什么区别?我尝试过两种输出都是零。

另外,智能指针怎么样才能确保它可以进行零初始化?

std::unique_ptr<int[]> p = std::make_unique<int[]>(100);

未初始化的 a 包含零的一个可能的实际原因是 new 从操作系统获取了零初始化的内存。例如,在 Linux 中,当您使用 mmap(并且 new 可以在内部使用它来分配大块)时,您会获得零初始化的内存。 - Evg
澄清之前的评论:那是针对你的情况的解释,而不是一般规则。在C++中读取未初始化的内存是未定义行为。任何事情都可能发生。 - MSalters
1个回答

7

new int[100] 执行默认初始化,所有元素将被初始化为不确定的值。注意,从中读取会导致未定义行为,任何结果都有可能发生。

  • 否则,不会执行任何操作:自动存储期对象(及其子对象)将被初始化为不确定的值。

new int[100]() 执行值初始化,因此所有元素都将被零初始化0

3) 如果T是数组类型,则数组的每个元素都将进行值初始化

4) 否则,该对象将进行零初始化

编辑

std::make_unique采用第二种初始化方式。

2) Constructs an array of unknown bound T. This overload only participates in overload resolution if T is an array of unknown bound. The function is equivalent to:

unique_ptr<T>(new typename std::remove_extent<T>::type[size]())

注意: 使用std::make_unique_for_overwrite使用第一种方法。

5) Same as (2), except that the array is default-initialized. This overload only participates in overload resolution if T is an array of unknown bound. The function is equivalent to:

unique_ptr<T>(new typename std::remove_extent<T>::type[size])

谢谢,智能指针怎么样了?我已经编辑了我的原始问题。 - Biao Cao
@BiaoCao 答案已修订。 - songyuanyao
明白了,非常有帮助。 - Biao Cao
1
在C++20中,我们将拥有std::make_unique_for_overwrite来进行默认初始化。 - Evg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接