c++ - unique_ptr 可以在不泄漏内存的情况下与负索引一起使用吗?

标签 c++ memory-leaks c++11 smart-pointers

我读了Are negative array indexes allowed in C?并发现有趣的是负值可以用于数组的索引。我用 c++11 unique_ptr 再次尝试了它,它也在那里工作!当然,删除器必须替换为可以删除原始数组的东西。这是它的样子:

#include <iostream>
#include <memory>

int main()
{
    const int min = -23; // the smaller valid index
    const int max = -21; // the highest valid index
    const auto deleter = [min](char* p)
    {
        delete [](p+min);
    };
    std::unique_ptr<char[],decltype(deleter)> up(new char[max-min+1] - min, deleter);

    // this works as expected
    up[-23] = 'h'; up[-22] = 'i'; up[-21] = 0;
    std::cout << (up.get()-23) << '\n'; // outputs:hi
}

我想知道内存泄漏的可能性是否非常非常小。在堆上创建的内存地址 (new char[max-min+1]) 在将 23 添加到它时可能会溢出并成为空指针。减去 23 仍会得到数组的原始地址,但 unique_ptr 可能会将其识别为空指针。 unique_ptr 可能不会删除它,因为它为空。

那么,之前的代码是否有可能泄漏内存,或者智能指针的行为方式是否安全?

注意:我实际上不会在实际代码中使用它;我只对它的行为感兴趣。

最佳答案

编辑: icepack提出一个有趣的观点,即在指针运算中只允许两个有效指针值:

§5.7 [expr.add] p5

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

因此,您的代码的 new char[N] - min 已经调用了 UB。


现在,在大多数实现中,这不会引起问题。然而,std::unique_ptr 的析构函数将(从这里开始预编辑答案):

§20.7.1.2.2 [unique.ptr.single.dtor] p2

Effects: If get() == nullptr there are no effects. Otherwise get_deleter()(get()).

所以是的,如果它确实映射到表示空指针值的任何值(很可能是 0,但不一定),那么您可能会在此处泄漏内存。是的,我知道这是针对单个对象的,但数组的行为完全相同:

§20.7.1.3 [unique.ptr.runtime] p2

Descriptions are provided below only for member functions that have behavior different from the primary template.

并且没有对析构函数的描述。

关于c++ - unique_ptr 可以在不泄漏内存的情况下与负索引一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13116534/

相关文章:

c - 如何为我的 php 扩展调试 'zend_mm_heap corrupted'

C++函数映射实现

c++ - 在 C++ 中编写 for/else 的简洁方法?

c++ - 如何使用 const 成员构造动态数量的类?

c++ - 在图上寻找最短距离——逻辑问题

C# 调用 IDisposable.Dispose() 与使对象为空

c++ - 子线程退出时如何通知父线程

c++ - 涵盖所有可能情况的右值表达式和左值表达式之间的区别的简洁、严格的定义是什么?

c++ - 查找单个字符串中重复次数最多和次多的字符

c++ - 对象销毁时内存泄漏