如何知道何时在C ++中调用delete和何时delete []?

西拉杰·卡兹

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

在实现析构函数时,我很难决定是使用内存delete还是delete[]释放内存。正如我在SO和其他网站上所读到的一样,没有一种可移植的方式来知道分配了多少个字节new[](或是否new使用了或new[])(新分配了多少个字节?

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

他是否会做 my_unique_ptr<int> ptr1(new int)

还是他会做 my_unique_ptr<int> ptr1(new int[5])

如果有办法,请告诉我!

这是我的类(简化后没有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说,valgrind在使用delete各处而不是在构造器中delete[]传递并传递多个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[]这是您的图书馆用户必须遵守的合同。如果不尊重,那就是UB。

  • 通过提供等价物帮助用户遵守此合同std::make_unique另请参见使用std :: make_unique优于new运算符的优势


这是否意味着删除成功释放了new []分配的所有5个整数?

不能。调用delete不是从newUB获得的内存

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章