我的问题位于我的代码注释中:
int* a = new int[0];// I've expected the nullptr according to my logic...
bool is_nullptr = !a; // I got 'false'
delete[] a; // Will I get the memory leaks, if I comment this row?
谢谢你。
我的问题位于我的代码注释中:
int* a = new int[0];// I've expected the nullptr according to my logic...
bool is_nullptr = !a; // I got 'false'
delete[] a; // Will I get the memory leaks, if I comment this row?
谢谢你。
对于 C++11,并给出您的代码:
int* a = new int[0];
根据 5.3.4/7,零是合法大小:
当 noptr-new-declarator 中表达式的值为零时,调用分配函数来分配一个没有元素的数组。
调用的操作符是按照 18.6.1.2 (强调我的):
void* operator new[](std::size_t size);
...
3 要求的行为:与operator new(std::size_t)相同。此要求对该功能的替换版本具有约束力。
4 默认行为:返回运算符 new(size)。
...引用 18.6.1.1 ...
void* operator new(std::size_t size);
3 要求的行为:将非空指针返回到适当对齐的存储 (3.7.4),否则抛出 bad_alloc 异常。此要求对该功能的替换版本具有约束力。
因此,返回的指针必须是非空的。
之后你确实需要delete[]
它。
在 C++03new int[0]
中会导致未定义的行为,因为两者之间的值[]
必须是严格的正值 - 零不好(5.3.4/6“新”)。所以问事后是否有内存泄漏在某种意义上是没有意义的。
在 C++11new int[0]
中,调用分配器以分配零长度数组(5.3.4/7“新”)。如果分配请求成功,则返回一个指针 - 标准中没有说明该指针指向的块包含多少内存,除了它必须至少是请求的大小。但是,它至少具有分配至少一个字符的效果,因为分配器在释放该地址之前不能再次返回该地址。实际上,簿记开销将超过一个字符。
是的,有一个泄漏,它不依赖于实现。
这个新表达式不能产生空指针。它通过调用operator new[]
来分配内存,这是“将非空指针返回到适当对齐的存储,否则抛出bad_alloc
异常”所必需的(参见 C++11 §18.6.1.1/3 和 §18.6.1.2/3)。
此外,分配函数要求(第 3.7.4.1 节)要求对分配函数的每次调用都返回一个指针,该指针不同于所有其他已分配但尚未释放的指针。因此,实现不能简单地拥有一个它总是返回的“空分配”指针。
这样,每个数组形式的新表达式都会分配一些东西,即使范围为零。如果您不通过 释放该对象delete[]
,那么您已经泄漏了它。
是的,没有delete
就会有内存泄漏。
每个new
都必须与delete
. 即使程序员分配的大小为 0。由于对齐要求、管理开销或其他原因,分配器可能分配比请求更多的内存。
在这种情况下,是否会返回 a由实现定义您应该注意不要取消引用此指针,也不调用nullptr
,但delete
将导致内存泄漏。
调用delete
规则很简单:
“如果你打电话new
,你必须打电话delete
。”
更正:
正如其他答案中的引文已经清楚表明,它不能给你一个nullptr
.