何时删除动态分配的内存

When to delete dynamically allocated memory

本文关键字:内存 动态分配 删除 何时      更新时间:2023-10-16

我有这个类:

class stringlist {
public:
    typedef std::string str;
    void push(str);
    void pop();
    void print();
    void resize(size_t);
    size_t capacity();
    size_t size();
    stringlist() : N(15) {}
    stringlist(size_t sz) : N(sz) {}
private:
    size_t N;
    str* container = new str[N];
};

以下是测试类的测试程序:

stringlist slist(16);
slist.push("One");
slist.push("Two");
slist.push("Three");
std::cout << "Capacity: " << slist.capacity() << std::endl;
std::cout << "List size: " << slist.size() << std::endl;
slist.print();

我不确定何时以及如何删除动态管理的内存。我需要调用析构函数吗,~stringlist() { delete [] container; }?由于new用于创建数据成员,因此我不确定是否允许我删除该成员。

C++有一个经验法则:

new,一个delete

您的代码也不例外。 你new了一些东西;你必须delete它。

由于container是在stringlist的构造函数中new的,所以你应该在stringlist的析构函数中delete它。

不要直接调用析构函数。1 相反,您只需允许在对象的正常释放中调用析构函数,无论是通过delete还是通过自动(即"堆栈")销毁。


1 您不直接调用析构函数:通常。 一个例外是使用放置new时,您在这里没有这样做。 如果您不知道是否需要使用放置 - new那么您不需要。

您主要有两种情况:

  • 堆栈上分配的变量。当它超出范围时,编译器会自动解除分配它。注意不要在变量被解除分配时访问变量(例如,通过指针)。

  • 通过语句在堆上分配的变量。在这里,您必须在不再需要该变量时显式调用 delete。注意不要创建内存泄漏(即,通过 new 分配的变量不再被引用,因此无法删除)。

您的代码是第一种示例。

对于第二种情况,如果您不想记住需要删除哪些变量(以及何时删除),则可以使用智能指针(在 Boost 库中可用或在 C++11 标准中本机提供)。有关更多信息,请参阅此处。

简单规则:

  • 将任何新的/新的[]与删除/删除[] 配对
  • 或将删除委托给智能指针(例如 std::unique_ptr 或 std::shared_ptr)

修复您的案例:

stringlist() : N(15), container(new str[N]) {}
stringlist(size_t sz) : N(sz), container(new str[N]) {}
// and
~stringlist() { delete [] container; }
// and
private:
size_t N;
str* container;