0

我有这堂课:

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用于创建数据成员,我不确定是否允许删除该成员。

4

3 回答 3

3

C++中有一条经验法则:

对于每一个new,一个delete

你的代码也不例外。你new编辑了一些东西;你必须delete这样做。

既然containernew在 的构造函数中编辑stringlist的,你应该deletestringlist的析构函数中。

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


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

于 2013-11-06T15:44:13.783 回答
2

你主要有两种情况:

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

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

您的代码是第一类的示例。

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

于 2013-11-06T15:35:31.463 回答
2

简单规则:

  • 将任何 new/new[] 与 delete/delete[] 配对
  • 或将删除委托给智能指针(例如 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;
于 2013-11-06T15:45:17.557 回答