Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 释放分配的内存_C++_Raii - Fatal编程技术网

C++ 释放分配的内存

C++ 释放分配的内存,c++,raii,C++,Raii,这是好的做法吗?或者我应该用函数替换{和}之间的代码块吗?它可以重复使用(我承认),但我这样做的唯一动机是取消分配colsum,因为它是巨大的,并且不是必需的,因此我可以释放分配的内存 vector<double> C; { vector<double> colsum; A.col_sum(colsum); C = At*colsum; } doSomething(C); 向量C; { 向量列和; A.col_sum(colsum); C=At*co

这是好的做法吗?或者我应该用函数替换
{
}
之间的代码块吗?它可以重复使用(我承认),但我这样做的唯一动机是取消分配
colsum
,因为它是巨大的,并且不是必需的,因此我可以释放分配的内存

 vector<double> C;
 {
  vector<double> colsum;
  A.col_sum(colsum);
  C = At*colsum;
 }
 doSomething(C);
向量C;
{
向量列和;
A.col_sum(colsum);
C=At*colsum;
}
剂量测定法(C);

在我的书中,使用括号来确定自动变量的范围是可以的,但是通常如果你发现自己经常这样做,特别是在同一个函数中多次这样做,那么你的函数可能做了太多不同的事情,应该被分解。

向量的数据总是动态分配的。只有簿记数据存储在堆栈上。即使不是这样,堆栈内存分配基本上是免费的。在大多数体系结构上,从堆栈中取消分配只是更改寄存器的值

编辑

关于动态解除分配,必须在某个点(特别是函数末尾)解除分配。在您想要分配更多内存而内存不足之前,您实际上不会丢失任何内存。在你真的遇到问题之前,是否真的需要关注解除分配发生的确切时间

/EDIT

但这有什么意义呢?你似乎真的过早地关注优化


如果你想重构你的代码,为了清晰而不是性能。Vector不会在堆栈上存储内存。只有向量对象本身存储在那里,它不是很大。像这样限定它的作用域会强制进行破坏,从而释放它已分配的内存


此外,我不确定ISO中是否规定实现必须从堆栈中弹出子范围变量。

正如其他人所指出的,向量内存没有在堆栈中分配。如果您想尽早释放内存,常用的习惯用法是:

vector<double> C;
vector<double> colsum;
A.col_sum(colsum);
C = At*colsum;
    std::vector<double>().swap(colsum);
doSomething(C);
向量C;
向量列和;
A.col_sum(colsum);
C=At*colsum;
std::vector().swap(colsum);
剂量测定法(C);
这将创建一个临时向量,并用大向量交换内容。在指令结束时,将销毁临时文件并释放内存。您将得到一个空向量


请注意,
colsum.resize(0)
colsum.clear()
不需要释放可用内存,而且在许多情况下,他们不会假设如果向量以前增长到该大小,它很可能会再次这样做。

如果内部代码将在其他地方重用,请将其分离为一个函数。如果频繁调用内部代码(如在循环中),则可能需要对其进行重构,以避免在循环中不断创建和销毁向量。否则,我不认为按照你的建议去做是不好的做法。

+1:对于分解它的建议-使代码更具可重用性/可读性:-)@bshileds:问题中所述的主要目的是强制释放向量。这就是你的意思吗(从你的评论来看似乎是这样)?@Jacob我理解你的意图,我是说这是一种有效的方法,比使用其他答案所建议的
swap
功能更干净,因为它使用了RAII。它有它的位置,特别是对于使用
互斥对象或类似对象包装代码。但是你必须小心,因为通过使用括号,你承认你有一组额外的变量,你想把它们分开,并在它们自己的范围内使用它们来做一些中间处理。你最好有一个很好的理由不要让那个块有它自己的功能,因为它闻起来确实像一个。不是真的。当
colsum
超出范围时,它将释放与其关联的内存。问题有点不精确,但很明显,问题是动态分配的内存,而不是使用的堆栈内存。取决于向量的大小,这可能是一个非常有效的堆内存使用问题,我不认为您可以自动将其作为预成熟优化进行注销。将内存分配到函数结束之前不会造成任何影响。如果您发现实际上遇到了内存不足的情况,那么您的优化已经成熟。杰梅林也提出了一个很好的观点。我甚至不确定是否有任何保证可以在收盘时解除分配。它可能会一直等到函数结束。有几种方法可以释放向量内存,而不必经历那些麻烦(例如,
std::vector().swap(colsum);
)我已经写了一个关于这个问题的答案。不,范围行为是定义良好的。变量超出作用域,对象被破坏,内存将被释放。据我所知,变量在函数结束前(即使它超出作用域)都不能保证调用其解构器,因此这可能不是你想要的。对于那些认为这不起作用的人,请参见Nevermind,我想我错了;在函数退出之前,
vector colsum
本身的内存不能保证被回收,但一旦它离开作用域,它的析构函数就会被回收。@BlueRaja:这正是我的观点。我的问题是,我是否应该为此编写一个函数,或者这是否被认为是“良好”的编程实践。但这是否比使用大括号来限制范围更好?虽然swap技巧是众所周知的,但它是一种迂回的方式来表达您想要做的事情。为了清除向量,我将使用swap技巧,因为这是一种常见的习惯用法,但我同意scope有它的优点。第一个是标识符可以自由重用,第二个是它将适用于没有
swap
等价物的类型(例如作用域锁)
{lock(m