C++ 何时删除动态分配的内存

C++ 何时删除动态分配的内存,c++,C++,我有这门课: 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) {} p

我有这门课:

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 slist(16);
滑动推压(“一”);
滑动推压(“两”);
滑动推压(“三”);

std::cout您主要有两种情况:

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

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

您的代码是第一类的示例


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

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

对于每一个
新的
,一个
删除

你的代码也不例外。你有了新的东西;您必须
删除它

由于
容器
字符串列表
的构造函数中是
新建的
,因此应该
字符串列表
的析构函数中删除它

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


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

简单规则:

  • 将任何新建/新建[]与删除/删除[]配对
  • 或将删除委托给智能指针(例如std::unique\u ptr或std::shared\u 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;

N
在这里应该是
const
。这太傻了。为什么不直接使用
向量
并将其处理掉呢?简单地说,在我的实现中,添加
~stringlist(){delete[]container;}
应该可以解决问题了?@Dochevsky:看起来不错。我可能会让析构函数
虚拟化
,顺便说一句,你的
新的
看起来很虚假。它需要在构造函数中。这是一个良好的惯例还是一个必要的要求?它似乎能按预期工作。如果
new
不在构造函数中,析构函数是否会不能正常工作?在C++03中,
new
必须在构造函数中。在C++11中,我不确定。