一个简单的测试应用程序:
cout << new int[0] << endl;
输出:
0x876c0b8
因此,看起来好像可行。标准对此有何说法?“分配”空的内存块总是合法的吗?
一个简单的测试应用程序:
cout << new int[0] << endl;
输出:
0x876c0b8
因此,看起来好像可行。标准对此有何说法?“分配”空的内存块总是合法的吗?
Answers:
从5.3.4 / 7起
当直接新声明器中表达式的值为零时,将调用分配函数以分配不包含任何元素的数组。
从3.7.3.1/2起
取消解引用作为零大小请求返回的指针的效果是不确定的。
也
即使[by new]请求的空间大小为零,请求也可能失败。
这意味着您可以执行此操作,但是您不能合法地(在所有平台上以明确定义的方式)取消对所获得的内存的引用-您只能将其传递给array delete-并且应该删除它。
这是3.7.3.1.2后面的句子的一个有趣的脚注(即,不是标准的规范性部分,但出于说明目的而包括在内)
[32。目的是通过调用malloc()或calloc()使操作符new()可以实现,因此规则基本相同。C ++与C的不同之处在于C ++要求零请求以返回非null指针。
new[]
与delete[]
-大小时,您都可以期待内存泄漏。特别是,在调用时,new[i]
您需要的内存比要分配的内存要多一些,以存储数组的大小(以后delete[]
在分配时使用)
是的,这样分配零大小的数组是合法的。但是您还必须删除它。
int ar[0];
为什么新可以吗?
sizeof (type)
预计永远不会返回零。参见例如:stackoverflow.com/questions/2632021/can-sizeof-return-0-zero
标准对此有何说法?“分配”空的内存块总是合法的吗?
每个对象都有一个唯一的标识,即一个唯一的地址,这意味着一个非零的长度(如果要求零字节,则实际的内存量将静默增加)。
如果您分配了多个这些对象,那么您会发现它们具有不同的地址。
operator []
还可以将数组的大小存储在某个位置(请参见isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array)。因此,如果实现通过数据分配字节数,则可以只分配字节数和0字节数据,返回1-past-last指针。
operator new[]
应返回不同的指针。顺便说一句,new expression
还有一些附加规则(5.3.4)。我找不到任何线索来说明new
实际上分配0大小实际上是必需的。抱歉,我不满意,因为我发现您的答案不是回答问题,而是提供一些有争议的陈述。
new[]
实现有可能返回没有映射动态内存的范围内的地址,因此不真正使用任何内存(使用地址空间时)
while(!exitRequested) { char *p = new char[0]; delete [] p; }
循环而不循环指针的计算机在可能耗尽地址空间之前会陷入尘土,但是在具有32位指针的平台上,它将是远没有合理的假设。
是的,使用分配0
大小块完全合法new
。您根本无法做任何有用的事情,因为没有有效的数据可供您访问。int[0] = 5;
是非法的。
但是,我认为,标准允许之类的东西malloc(0)
来回报NULL
。
您仍然仍然需要delete []
从分配中返回的任何指针。