内存泄漏C++.编程风格
Memory Leaks in C++. Programming style
对于小过程,我们可以通过以下方式防止异常情况下的内存泄漏:
proc() {
//allocate memory for matrix
try {
}
catch {
//free matrix memory
}
...
//free matrix memory
}
如果我们的程序更复杂:
proc() {
//allocate memory for matrix
try {
}
catch {
//free matrix memory
}
...
try {
}
catch {
//free matrix memory
}
...
try {
}
catch {
//free matrix memory
}
...
//free matrix memory
}
它看起来有些笨拙。是否存在更好的方法,更好的内存泄漏控制编程风格?据我所知,C++已经auto_ptr,我们可以开发程序而不关心内存释放。
proc() {
//allocate auto_ptr
try {
}
catch {
}
...
}
但是,据我所知,auto_ptr甚至不适用于数组。因此,在一般情况下,这是不可接受的方式。
auto_ptr
并不是一个独特的情况。这不是"auto_ptr
或什么都没有"。auto_ptr
是一般编程习惯用法的一个例子,它处理资源分配/释放而不会泄漏。
这个成语叫做RAII。
这意味着资源应映射到一个对象,该对象管理资源的生存期,并确保在适当的时间清理资源。
在auto_ptr
的情况下,只需让一个类存储指向已分配内存的指针,并在该类的析构函数中调用指针上的delete
即可。
您可以对自己的 RAII 类执行相同的操作,使用它们而不是 auto_ptr
。但也有其他类型的智能指针,它们优先于auto_ptr
(实际上,在 C++11 中已弃用(。
它们是shared_ptr
(引用计数的智能指针,当最后一个引用存在时删除对象(和scoped_ptr
(更安全但有限的等价物,可以在C++03中实现auto_ptr
(,以及unique_ptr
,C++11替代auto_ptr
,解决了auto_ptr
遇到的问题。unique_ptr
可以安全地用于阵列和标准容器。
所以你不应该使用auto_ptr
,但你绝对应该使用其他类型的智能指针,以及一般的RAII。
不要在客户端代码中使用手动内存分配!
相反,设计一个负责自己业务的Matrix
类。然后你可以说,
void proc()
{
Matrix m1; // might throw
// ...
Matrix m2; // might also throw
// ...
}
在任何地方的任何异常中,所有已经存在的对象都会被销毁,如果你设计了正确的类,那么这将释放所有动态资源。
非常非常婴儿的Matrix
类示例:
struct Matrix
{
Matrix(size_t m, size_t n) : buf(m * n), M(m), N(n) { }
int & operator(size_t i, size_t j) { return buf[i * N + j]; }
private:
std::vector<int> buf;
size_t M;
size_t N;
};
我其实很懒,把所有实际的动态数据都放到一个std::vector
;不需要重新发明轮子!(或者只是使用Boost.MultiArray
还有更多可用的智能指针,例如来自 Boost,其中一些已被纳入新的 C++ 标准。
尽管如此,对于数组,"正确的选择"是只使用 STL 容器,特别是std::vector
如果您使用动态数组 - 在当前编译器上,它具有与"常规"数组相同的性能。
请记住,这个问题比内存更普遍:必须获取和释放的每个资源都会产生相同的问题,C++解决方案是使用类似智能指针的类来包装它们(在构造函数中获取所有权,在析构函数中销毁资源(;这个成语通常被称为RAII(资源获取是初始化(。
请注意,在C++有异常的代码中,这似乎是处理问题的唯一实用方法(因为该语言不提供finally
块或using
语句,并且由于异常,每条指令都是潜在的返回路径(。
你是对的,自动指针不适用于数组,就像 C 样式指针可用于引用数组一样。 这就是为什么还有其他容器,例如std::vector
,std::deque
等。 您只需使用std::vector<std::shared_ptr<T> >
.
- Qt VTK交互风格的信号到小部件
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 我可以使用条件运算符初始化C风格的字符串文字吗
- Visual Studio 2019:插入多个C++风格的单行注释
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 模板元编程:如何将参数包组合成新的参数包
- 以C++元编程风格实现 RLE 算法
- C++宏中的函数式编程风格:这是否记录在任何地方
- 为什么除了编程风格之外还使用成语"Reference to pointer"?
- C++方法良好的编程风格
- 如何以"functional"编程风格显示 QImage
- 面向对象编程风格
- 内存泄漏C++.编程风格
- 浮点运算的编程风格
- "Game Coding Complete"的编程风格
- 正确使用智能指针和编程风格
- 编程风格:对象与引用或值通道?(c++)
- 编程风格-如何使用clang-format缩进c++ pragma
- 编程模板的风格