内存分配和0大小:我可以获得内存泄漏吗?

时间:2013-07-02 07:16:33

标签: c++ memory-leaks new-operator

我的问题位于我的代码评论中:

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?

谢谢。

5 个答案:

答案 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