为什么堆分配数组的大小需要初始化器-列表初始化

Why is the size of a heap-allocated array required with initializer-list initialization?

本文关键字:初始化 列表 分配 数组 为什么      更新时间:2023-10-16

虽然我可以写

int n[] {1, 2, 3};

我不能写

int *m = new int[] {1, 2, 3};

应该是

int *m = new int[3] {1, 2, 3};

这是什么原因?

请记住,new在c++中实际上是一个操作符。

这是因为new操作符的定义方式;也就是说,它需要请求内存的大小作为一个明确的输入参数。因此,它不能通过初始化列表成员的计数来推导。

要理解这一点,您需要了解new操作符是如何工作的。New返回一个指向新分配的内存块开始的指针。所以当我们输入

int* p = new int;

分配的内存只包含一个元素。但是当我们输入

int* foo = new [3];

为int类型的元素分配了一块内存,其中"3"是整型元素的内存块号。这告诉编译器为3个整数分配内存。当我们这样做

int* p = new int[3]{1,2,3}

我们要求编译器分配3个存储整型值的内存位置。与此同时,我们也为这些内存位置赋值。

现在如果我们这样做

 int* p = new int[] {1,2,3}

我们没有告诉编译器要分配多少内存,但同时我们试图分配3个内存位置,但我们没有分配那么多内存。在这种情况下,编译器只分配1块内存。第一个值被赋值。这将导致运行时错误。

现在奇怪的是,如果下面是允许的,并且编译器足够智能地分配3个值

int n[] = {1, 2, 3}

为什么不呢

int *p = new int [] {1,2,3}

我认为这是问题所在,因为新操作符是如何设计的。你可以尝试重载new操作符来解决这个问题。

希望对你有帮助。

编辑:我尝试了一些虚拟代码VS.似乎如果你这样做

int* p = new int [] {1,2,3}

这是一个崩溃。但是当你这样做

int* p = new int []{1}

这完全没问题。这证明编译器将其解释为仅分配1块内存的命令。