14

我的问题位于我的代码注释中:

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?

谢谢你。

4

5 回答 5

16

对于 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[]它。

于 2013-07-02T07:33:27.220 回答
10

在 C++03new int[0]中会导致未定义的行为,因为两者之间的值[]必须是严格的正值 - 零不好(5.3.4/6“新”)。所以问事后是否有内存泄漏在某种意义上是没有意义的。

在 C++11new int[0]中,调用分配器以分配零长度数组(5.3.4/7“新”)。如果分配请求成功,则返回一个指针 - 标准中没有说明该指针指向的块包含多少内存,除了它必须至少是请求的大小。但是,它至少具有分配至少一个字符的效果,因为分配器在释放该地址之前不能再次返回该地址。实际上,簿记开销将超过一个字符。

于 2013-07-02T07:31:46.083 回答
7

是的,有一个泄漏,它不依赖于实现。

这个新表达式不能产生空指针。它通过调用operator new[]来分配内存,这是“将非空指针返回到适当对齐的存储,否则抛出bad_alloc异常”所必需的(参见 C++11 §18.6.1.1/3 和 §18.6.1.2/3)。

此外,分配函数要求(第 3.7.4.1 节)要求对分配函数的每次调用都返回一个指针,该指针不同于所有其他已分配但尚未释放的指针。因此,实现不能简单地拥有一个它总是返回的“空分配”指针。

这样,每个数组形式的新表达式都会分配一些东西,即使范围为零。如果您不通过 释放该对象delete[],那么您已经泄漏了它。

于 2013-07-02T07:31:02.677 回答
4

是的,没有delete就会有内存泄漏。

每个new都必须与delete. 即使程序员分配的大小为 0。由于对齐要求、管理开销或其他原因,分配器可能分配比请求更多的内存。

于 2013-07-02T07:17:45.803 回答
4

在这种情况下,是否会返回 a由实现定义nullptr,但您应该注意不要取消引用此指针,也不调用delete将导致内存泄漏。

调用delete规则很简单:
“如果你打电话new,你必须打电话delete。”

更正:
正如其他答案中的引文已经清楚表明,它不能给你一个nullptr.

于 2013-07-02T07:18:24.973 回答