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中,我不确定。