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