c++ - 如何知道何时在 C++ 中调用 delete 以及何时调用 delete[]?

标签 c++ memory-management new-operator smart-pointers delete-operator

我正在实现类 my_unique_ptrmy_shared_ptr模仿标准库智能指针 std::unique_ptrstd::shared_ptr更好地了解它。

在实现析构函数时,我很难决定是否使用 deletedelete[]释放内存。就我在 SO 和其他网站上阅读的内容而言,没有可移植的方式可以知道 new[] 分配了多少字节。 (或者是否使用了 newnew[] )( How many bytes were allocated by new? )

在实现类 my_unique_ptr 时我无法知道用户将从构造函数请求多少字节,即

他会不会做my_unique_ptr<int> ptr1(new int)

或者他会做 my_unique_ptr<int> ptr1(new int[5])

如果有办法请告诉我!

这是我的类(class)(经过简化且没有 cpy/move 构造函数):

template<typename ValueType>
class my_unique_ptr {

    ValueType *internal_ptr = nullptr;

public:
    
    // Default constructor
    my_unique_ptr() {
       internal_ptr = nullptr;
    }

    // Paramterized constructor
    explicit my_unique_ptr(ValueType *ptr) {
       if (ptr)
        internal_ptr = ptr;
    }

    // Destructor
    ~my_unique_ptr() {
       
        // How do I know whether to use
           delete ptr;

        // or
           delete[] ptr;
        
     }

我在某处读到编译器会跟踪 new[] 的参数然后由 delete[] 使用正确释放内存。另请阅读“程序员有责任将 newdeletenew[]delete[] 匹配”。但是我如何在我的类里面对此进行编程,以便它始终匹配正确的运算符?

旁注:

正在运行 valgrind使用 delete 时到处而不是delete[]并通过超过 1 int (比如 new int[5] )在我的构造函数中,Valgrind 说所有内存块都被释放了,没有泄漏的机会! (尽管显示类似 mismatched new[] with delete 的警告。这是否意味着 delete 成功释放了 ints 分配的所有 5 个 new[]?请帮忙。 我在 Ubuntu 18.04并使用 gcc 7.5.0 .

最佳答案

你是对的,你不知道内存是否由 new 分配。或 new[] .但是你甚至不知道一个内存存储了一个自动持续时间对象。例如。您的用户可以:

int a = 24;

my_unique_ptr<int> ptr1(&a); // oups

你无法知道这一点。所以做标准库做的事情:

  • 对数组类型进行专门化,例如template <class T> class my_unique_ptr<T[]>那叫delete[]在析构函数上。

  • 要求 my_unique_ptr<T>必须使用从 new 获得的内存进行初始化和 my_unique_ptr<T[]>必须使用从 new[] 获得的内存进行初始化.这是您图书馆的用户必须遵守的契约(Contract)。如果没有得到尊重,那就是 UB。

  • 通过提供 std::make_unique 的等效项来帮助用户遵守此契约(Contract).另见 Advantages of using std::make_unique over new operator


Does this mean delete is successfully freeing all the 5 ints allocated by new[]

没有。打电话delete在不是从 new 获得的内存上是UB。

关于c++ - 如何知道何时在 C++ 中调用 delete 以及何时调用 delete[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62547716/

相关文章:

c++ - 继承模板类并连接到信号

c++ - 打印数组字符串的方法

c++ - 编译时生成应在构造函数中创建的非 constexpr 对象的数组

Delphi内存管理设计策略: Object or Interface?

arrays - 标量上下文中新 'each @array'的行为

C++ - 函数指针和类

memory-management - 如何衡量 Erlang 垃圾收集器的性能?

iphone - 内存泄漏 - 应用程序退出并显示信号 9

c++ - 放置新行为等效

c++ - 我相信这是 clang 中的一个错误,与构造函数抛出的放置新表达式有关