STL容器中的内存释放
memory freeing in STL containers
我有一个对象列表:
struct reply_t {
unsigned int xid;
char *buf;
};
std::list<reply_t> > replies;
我想删除该列表中的一些元素(例如xid <= confirmed_id
)。我喜欢std :: remove_if
提供的简洁性。
remove_if(replies.begin(), replies.end(),
[&confirmed_id](const reply_t &arg) { return arg.xid <= confirmed_id; });
问题是,这并不能释放buf
(它们被分配到其他地方)。有没有一种优雅的方法来处理这个问题?它是否像在对象析构函数中添加free(buf)一样简单?
您可以为reply_t实现一个析构函数,用于删除buf:
struct reply_t {
unsigned int xid;
char *buf;
~reply_t() { delete buf; }
};
这段代码是C和C++的邪恶沙拉。
在C++中,每个类都应该有一个构造函数来累积对象所需的内容,还有一个析构函数来释放对象在其生命周期中获得的任何资源。
您提供的结构是一个纯C结构,它既不符合C++容器,也不符合C++语言哲学。它无法清除它产生的"垃圾",从而导致泄漏。
构造函数累积在C++语言中调用的Destructor释放,即RAII习惯用法。
你的对象应该有一个合适的构造函数和析构函数:
struct reply_t {
unsigned int xid;
char *buf;
reply_t() xid(0),buf(nullptr){}
~reply_t() { delete buf; }
};
正如其他人所说,是的,您可以添加析构函数来进行删除。他们遗漏的是,在执行此操作时,必须还实现一个复制构造函数和一个赋值运算符。否则,当您将其中一个对象复制到列表中时,复制的对象将删除缓冲区,然后该对象的副本也将删除缓冲区时。这是个坏消息。或者,正如已经建议的那样,使用std::string
而不是char*
;这样,编译器生成的复制构造函数和赋值运算符将做正确的事情。
签名不需要有常量&,但是函数不能修改传递给它的对象。
以下是remove_if 的可能实现
template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
first = std::find_if(first, last, p);
if (first != last)
for(ForwardIt i = first; ++i != last; )
if (!p(*i))
*first++ = std::move(*i);
return first;
}
因此,也许您可以通过这段代码来实现,但您应该通过为类添加析构函数或使用std::string而不是char*来实现它。
remove_if(replies.begin(), replies.end(),
[&confirmed_id](reply_t &arg)
{
if(arg.xid <= confirmed_id)
{
delete[] arg.buf;
arg.buf = nullptr;
return true;
}
return false;
});
相关文章:
- 包含矢量指针的结构的内存释放问题
- Valgrind 声称内存释放中的自由空间太多
- 当 C 和 C++ 中严格要求内存释放时
- C++ 中指针变量的内存释放
- 德克内存释放
- 临时对象 c++ 的内存释放
- C 全局对象变量内存释放
- C++矢量动态内存释放/删除
- 从 cv::Mat 初始化的 IplImage 的内存释放
- SWIG类型映射中的内存释放
- STL容器中的内存释放
- QWebView内存释放
- 内存释放 C++
- 大返回值(如字符串)的内存释放如何在C++中发生
- 重新分配之前的内存释放
- Linux C++ 中的内存释放
- VS2012编译器奇怪的内存释放问题
- 调试断言失败!错误的内存释放
- 负责 COM 互操作中的内存释放
- imread命令后OpenCV矩阵内存释放