如何使用我的函数类删除动态数组?

时间:2020-11-06 20:54:27

标签: c++ dynamic-memory-allocation

再次使用模板。现在,我正在尝试编写一个Deleter函数类,以使其类似于一种delete的语言,因此这是我的尝试:

class Deleter
{
public:
    template <typename T>
    void operator()(T*) const;
};

template <typename T>
void Deleter::operator()(T* ptr) const
{
    std::cout << "freeing memory...\n";
    delete ptr;
}


int main()
{

    int* pi = new int(7);
    char* cp = new char[100];
    strcpy(cp, "hi there!");

    Deleter del;
    del(pi); // 1- argument deduced is int*
    del(cp); // 2- argument deduced is char*

    std::cout << "\ndone\n";
}

我已经将调用操作符作为模板进行了重载,因此在编译时它知道参数的静态类型。 (我可以使它成为非模板,用void*代替T。)

它工作正常,但我肯定statement 2会导致内存泄漏,因为我将指向动态数组的指针传递给delete,该指针对指向动态对象而不是数组的指针起作用,因为已经了解到,对于尚未使用相应的new运算符分配的对象,调用delete是不确定的行为。

因此,我的代码中是否有变通办法,以便可以调用del[]cp;?谢谢!

1 个答案:

答案 0 :(得分:3)

您不能将delete与分配给new[]的内存一起使用,反之亦然,不能将delete[]与分配给new的内存一起使用。这正是std::unique_ptrstd::shared_ptr有专门知识来决定何时分别将delete[]delete用于数组和非数组内存的原因(通过std::default_delete模板)。

您也将必须以类似的方式来专门化Deleter。只有您Deleter的用户,而不是Deleter本身,才能决定要使用哪种专业化,因为只有该用户才知道有关如何分配内存以及如何分配内存的信息。释放。

例如:

template <typename T>
class Deleter
{
public:
    void operator()(T* ptr) const {
        std::cout << "freeing memory using 'delete'...\n";
        delete ptr;
    }
};

template <typename T>
class Deleter<T[]>
{
public:
    template <typename U>
    void operator()(U* ptr) const {
        std::cout << "freeing memory using 'delete[]'...\n";
        delete[] ptr;
    }
};

int main()
{
    int* pi = new int(7);
    char* cp = new char[100];
    strcpy(cp, "hi there!");

    Deleter<int> del1;
    del1(pi); // uses 'delete'...

    Deleter<char[]> del2;
    del2(cp); // uses 'delete[]'...

    std::cout << "\ndone\n";
}

Live Demo