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

And*_*man 14 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?
Run Code Online (Sandbox Code Playgroud)

谢谢.

Ton*_*roy 16

对于C++ 11,并给出了您的代码:

int* a = new int[0];
Run Code Online (Sandbox Code Playgroud)

根据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默认行为:返回operator new(size).

......参考18.6.1.1 ......

void* operator new(std::size_t size);
Run Code Online (Sandbox Code Playgroud)

3必需的行为:将非空指针返回到适当对齐的存储(3.7.4),否则抛出bad_- alloc异常.此要求绑定在此函数的替换版本上.

因此,返回的指针必须为非null.

之后你确实需要delete[]它.

  • @Bush:老实说,我觉得有点伤心,你花了他的时间用你已经被告知过的东西,但是你有它...... (4认同)

Mic*_*urr 10

在C++ 03中new int[0]导致未定义的行为,因为它之间的值[]必须是严格正值 - 零是不好的(5.3.4/6"新").因此,询问之后是否存在内存泄漏在某种意义上是毫无意义的.

在C++ 11 new int[0]中,调用分配器来分配零长度数组(5.3.4/7"New").如果分配请求成功,则返回一个指针 - 标准中没有任何内容表明该指针所指向的块所包含的内存量,除了它必须至少是所请求的大小.但是,它至少具有分配至少一个字符的效果,因为分配器在释放之前不能再次返回该地址.在实践中,簿记开销将不止一个字符.

  • 关于C++ 03的评论是完全错误的.在C++ 03(§5.3.4/ 6)中:"direct-new-declarator中的表达式应具有带有非负值的整数或枚举类型(3.9.1)." 0是非负值.(事实上​​,自C++ 98以来,这里没有任何变化.) (4认同)

Jam*_*lis 7

是的,存在泄漏,并且它不依赖于实现.

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

此外,分配函数要求(第3.7.4.1节)要求对分配函数的每次调用都返回一个指针,该指针与已分配但尚未解除分配的所有其他指针不同.因此,实现不能简单地具有它总是返回的单个"空分配"指针.

这样,每个数组形式的新表达式都会分配一些东西,即使范围是零.如果你没有通过解除分配该对象delete[],你就泄露了它.