一个简单的测试应用程序:
cout << new int[0] << endl;
输出:
0x876c0b8
看起来是可行的。标准是怎么说的?“分配”空内存块总是合法的吗?
一个简单的测试应用程序:
cout << new int[0] << endl;
输出:
0x876c0b8
看起来是可行的。标准是怎么说的?“分配”空内存块总是合法的吗?
当前回答
标准是怎么说的?“分配”空内存块总是合法的吗?
每个对象都有唯一的标识,即唯一的地址,这意味着长度非零(如果您要求零字节,实际的内存量将无声地增加)。
如果你分配了多个这样的对象,你会发现它们有不同的地址。
其他回答
是的,像这样分配一个零大小的数组是合法的。但你也必须删除它。
从5.3.4/7
当direct-new-declarator中的表达式值为0时,将调用分配函数来分配一个不含元素的数组。
从3.7.3.1/2
取消引用作为零大小请求返回的指针的效果是未定义的。
Also
即使[new]请求的空间大小为零,请求也可能失败。
这意味着您可以这样做,但是您不能合法地(在所有平台上以一种定义良好的方式)解除对所获得的内存的引用—您只能将它传递给数组delete—并且您应该删除它。
这里有一个有趣的脚注(即不是标准的规范部分,但用于说明性目的)附在3.7.3.1/2的句子后面
[32。目的是通过调用malloc()或calloc()来实现operator new(),因此规则基本上是相同的。c++与C的不同之处在于要求零请求来返回一个非空指针。
我向你保证,新的int[0]花费你额外的空间,因为我已经测试过了。
例如, 内存使用情况
int **arr = new int*[1000000000];
明显小于
int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
arr[i]=new int[0];
}
第二个代码段的内存使用量减去第一个代码段的内存使用量就是新整数[0]所使用的内存使用量。
标准是怎么说的?“分配”空内存块总是合法的吗?
每个对象都有唯一的标识,即唯一的地址,这意味着长度非零(如果您要求零字节,实际的内存量将无声地增加)。
如果你分配了多个这样的对象,你会发现它们有不同的地址。
奇怪的是,c++要求操作符new返回一个合法的指针 即使请求的字节为零。(这听起来很奇怪 行为简化了语言中其他地方的事情。)
我发现Effective c++第三版在“第51项:写new和delete时坚持约定”中是这样说的。