C++ C++;new int[0]--它会分配内存吗?

C++ C++;new int[0]--它会分配内存吗?,c++,memory-management,new-operator,standards-compliance,C++,Memory Management,New Operator,Standards Compliance,一个简单的测试应用程序: cout << new int[0] << endl; 所以它看起来是有效的。标准对此有何规定?“分配”空内存块总是合法的吗?是的,这样分配零大小的数组是合法的。但您也必须将其从5.3.4/7中删除。 当直接新声明符中表达式的值为零时,将调用分配函数来分配不含元素的数组 从3.7.3.1/2开始 取消引用作为零大小请求返回的指针的效果未定义 也 即使[by new]请求的空间大小为零,请求也可能失败 这意味着您可以这样做,但您不能合法地(在所有

一个简单的测试应用程序:

cout << new int[0] << endl;

所以它看起来是有效的。标准对此有何规定?“分配”空内存块总是合法的吗?

是的,这样分配零大小的数组是合法的。但您也必须将其从5.3.4/7中删除。

当直接新声明符中表达式的值为零时,将调用分配函数来分配不含元素的数组

从3.7.3.1/2开始

取消引用作为零大小请求返回的指针的效果未定义

即使[by new]请求的空间大小为零,请求也可能失败

这意味着您可以这样做,但您不能合法地(在所有平台上以定义良好的方式)取消对所获得内存的引用—您只能将其传递给array delete—您应该将其删除

下面是附在第3.7.3.1/2节句子后面的一个有趣的脚注(即不是标准的规范性部分,但出于解释目的)

(32)意图是通过调用MalCube()或CalOrror()来实现操作符NeW(),因此规则基本相同。C++在要求零空指针返回零请求时与C不同。


是的,使用
new
分配
0
大小的块是完全合法的。由于没有可供您访问的有效数据,因此您无法使用它做任何有用的事情<代码>整数[0]=5是非法的

但是,我相信该标准允许像
malloc(0)
这样的东西返回
NULL

您仍然需要
删除[]
从分配中返回的任何指针

标准对此有何规定?“分配”空内存块总是合法的吗


每个对象都有一个唯一的标识,即一个唯一的地址,这意味着非零长度(如果请求零字节,实际内存量将以静默方式增加)

如果您分配了这些对象中的多个,那么您会发现它们有不同的地址

奇怪的是,C++要求运算符新返回合法指针。 即使请求零字节。(这听起来很奇怪 行为简化了语言中其他地方的事情。)


<>我发现有效的C++第三版本在“项目51:在编写新的和删除时遵守约定”这样说。

< p>我保证,新的INT(0)在测试之后会花费额外的空间。 比如说,, 的内存使用情况

int **arr = new int*[1000000000];
明显小于

int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
    arr[i]=new int[0];
}
int**arr=newint*[100000000];
对于(int i=0;i<100000000;i++){
arr[i]=新整数[0];
}

第二个代码段减去第一个代码段的内存使用量是用于大量新int[0]的内存。

+1非常有趣的问题-虽然我不确定它在实际代码中有多重要。@Zifre:我是出于好奇,但在现实世界中可能很重要,例如,当以某种方式计算已分配内存块的大小时,计算结果可能为零,则无需直接添加异常以不分配零大小的块。。因为它们应该在没有错误的情况下被分配和删除(如果只有零大小的块没有被取消引用)。因此,一般来说,这会更广泛地抽象出内存块是什么。@emg-2:在您的示例中,它实际上并不重要,因为delete[]在空指针上完全合法:-),它只是切线相关的-所以我在这里评论-但是C++在很多方面确保不同的对象有唯一的地址…即使它们不明确地需要存储。一个相关的实验是检查一个空结构的大小。详细说明Shmoopty的注释:特别是在用模板编程时(例如,像STD:分配器)的策略类模板,C++中通常有零大小的对象。通用代码可能需要动态分配这些对象,并使用指向它们的指针来比较对象标识。这就是为什么运算符new()为大小为零的请求返回唯一指针。虽然可以说不太重要/不常见,但同样的推理也适用于数组分配和运算符new[]()。您对此有引用吗?我们都知道,
intar[0]非法,为什么新的OK?有趣的是C++没有那么强,禁止零大小的对象。考虑空基类优化:在这里,空基类子对象的大小也可能为零。相比之下,C标准极力确保不会创建零大小的对象:例如,在定义malloc(0)时,它表示效果是使用一些非零参数运行malloc。在结构{…;tn[];}中;当没有为数组(FAM)分配空间时,它表示其行为就像“n”有一个元素一样。(在这两种情况下,以任何方式使用对象都是UB,比如x.n[0])我认为
sizeof(type)
永远不会返回零。请参阅示例:即使是所谓的“空基类优化”也只是因为坚持所有对象(而不是对象中的所有字节)必须具有唯一地址才相关。如果需要真正关心具有唯一地址的对象的代码以确保它们具有非零大小,那么C++可以变得更简单。对于MALOC,您是正确的——它是实现定义的。这通常被视为一种错误功能。我想一个有趣的问题是:如果给定大小为0,nothrow版本的new是否可以返回NULL?new和malloc的语义没有任何联系,至少按照标准是这样的。不说它们是。。。特别询问nothrow版本的new。@Evan-nothrow版本的new仅在请求失败时返回null-不仅仅是在请求大小为0@Neil的情况下-不是标准链接-而是通过意图链接(即,新运算符可以根据malloc实现,但不是相反的方式)-参见页脚
int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
    arr[i]=new int[0];
}