一个简单的测试应用程序:
cout << new int[0] << endl;
输出:
0x876c0b8
所以它看起来很有效。标准对此有何看法? “分配”空白内存块总是合法的吗?
答案 0 :(得分:222)
从5.3.4 / 7
当direct-new-declarator中的表达式的值为零时,调用分配函数来分配没有元素的数组。
从3.7.3.1/2
取消引用作为零大小请求返回的指针的效果未定义。
另外
即使[new]请求的空间大小为零,请求也会失败。
这意味着你可以做到,但你不能合法地(在所有平台上以明确定义的方式)取消引用你得到的内存 - 你只能将它传递给数组删除 - 你应该删除它。
这是一个有趣的脚注(即不是标准的规范部分,但包括用于说明目的)附于3.7.3.1/2的句子
[32。目的是通过调用malloc()或calloc()来实现operator new(),因此规则基本相同。 C ++与C的不同之处在于要求零请求返回非空指针。]
答案 1 :(得分:20)
是的,像这样分配一个零大小的数组是合法的。但你也必须删除它。
答案 2 :(得分:15)
标准对此有何评价? “分配”空白内存块总是合法的吗?
每个对象都有一个唯一的标识,即一个唯一的地址,这意味着一个非零长度(如果要求零字节,实际的内存量将无声增加)。
如果你分配了多个这些对象,那么你会发现它们有不同的地址。
答案 3 :(得分:14)
是的,使用0
分配new
大小的块是完全合法的。由于没有有效的数据供您访问,因此您无法对其执行任何有用的操作。 int[0] = 5;
是非法的。
但是,我认为该标准允许malloc(0)
之类的内容返回NULL
。
您仍然需要delete []
从分配中获得的任何指针。
答案 4 :(得分:1)
奇怪的是,C ++要求operator new返回一个合法的指针 即使请求零字节。 (要求这听起来很奇怪 行为简化了语言中其他地方的事情。)
我发现 Effective C ++ Third Edition 在&#34;项目51中表示:在编写新内容时删除约定&#34;。
答案 5 :(得分:0)
我向您保证,新的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 [0]的内存。