我的问题位于我的代码评论中:
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?
谢谢。
答案 0 :(得分: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必需行为:与运营商new(std :: size_t)相同 。此要求对替换具有约束力 这个功能的版本。
4默认行为:返回operator new(size)。
......引用18.6.1.1 ......
void* operator new(std::size_t size);
3必需行为:将非null 指针返回到适当对齐的存储(3.7.4),否则抛出bad_- 分配例外。此要求绑定在此函数的替换版本上。
因此,返回的指针必须为非null。
之后你需要delete[]
。
答案 1 :(得分:10)
在C ++ 03中new int[0]
导致未定义的行为,因为[]
之间的值必须是严格正值 - 零是不好的(5.3.4 / 6“新”)。因此,询问之后是否存在内存泄漏在某种意义上是毫无意义的。
在C ++ 11 new int[0]
中,调用分配器来分配零长度数组(5.3.4 / 7“New”)。如果分配请求成功,则返回一个指针 - 标准中没有任何内容表明该指针所指向的块所包含的内存量,除了它必须至少是所请求的大小。但是,它至少具有分配至少一个字符的效果,因为分配器在释放之前不能再次返回该地址。在实践中,簿记开销将不止一个字符。
答案 2 :(得分:7)
是的,存在泄漏,并且不依赖于实现。
这个新表达式不能产生空指针。它通过调用operator new[]
来分配内存,这需要“将非空指针返回到适当对齐的存储,否则抛出bad_alloc
异常”(参见C ++11§18.6.1.1/ 3)和§18.6.1.2/ 3)。
此外,分配函数要求(第3.7.4.1节)要求对分配函数的每次调用都返回一个指针,该指针与已分配但尚未解除分配的所有其他指针不同。因此,实现不能简单地只有一个“空分配”指针,它始终返回。
这样,每个数组形式的新表达式都会分配某些东西,即使范围为零。如果你没有通过delete[]
解除分配该对象,那么你已经泄露了它。
答案 3 :(得分:4)
是的,没有delete
会有内存泄漏。
每个new
都必须与delete
配对。即使程序员分配的大小为0.由于对齐要求,管理开销或其他任何原因,Allocator可能会分配比请求更多的内存。
答案 4 :(得分:4)
在这种情况下实现定义是否会返回你应该注意你也不要取消引用这个指针不调用nullptr
但是delete
将导致内存泄漏。
W.r.t致电delete
规则很简单:
“如果您致电new
,则必须致电delete
。”
的校正:强>
由于其他答案中的引文已经明确表示,它无法返回nullptr
。