涉及向量的C++内存分配问题

5
vector< int > vect;
int *int_ptr = new int(10);
vect.push_back( *int_ptr );

我知道每个“new”都需要在某个时候跟着一个“delete”,但是clear()方法是否可以清除这些内存?

那么用这种方法做同样的事情呢:

vector< int > vect;
int int_var = 10;
vect.push_back( int_var );

据我了解,clear() 调用变量的析构函数,但是在这个例子中,两个 vect.push_back() 方法都是将一个对象推入向量,而不是一个指针。那么第一个例子使用 int 指针需要使用除 clear() 之外的其他方式来清理内存吗?
3个回答

5

第一种方法泄漏了,因为向量从未接管分配的指针。实际上,它根本不包含指针,只包含值的副本。

第二种方法不会泄漏,因为没有动态分配内存(除了向量内部处理的内存,它将自行处理该内存)。


当你说它会自己处理内存,是指在我调用vector.clear()之后吗? - TheFuzz
当向量被销毁时,内存将被回收。clear()不会实际释放任何内存;向量将保留容量以防需要在以后再次增长。 - Fred Larson
那么,有什么阻止我完全不使用指针,而是创建临时堆栈变量,然后在需要时将它们推入向量中呢?由于某种原因,指针失去了它们的意义。 - TheFuzz
完全有可能(甚至很可能)你根本不需要指针。只有在对象的生命周期需要超过创建对象的作用域的生命周期时,才通常需要动态分配。 - Fred Larson
我必须问一下,您说当向量被销毁时,内存会被回收,那么当整个向量超出范围(或指向向量的指针被删除)时,如果向量内部的内存没有动态分配,那么里面的所有内容都将被删除吗? - TheFuzz
正确。向量分配的所有内容都将被释放。 - Fred Larson

5
当你在向向量中push_back添加数据时,你会向向量中添加一个副本。因此,在这两种情况下,原始数据仍然需要被释放。在第一种情况下,你需要删除它; 在第二种情况下,随着堆栈指针超出范围,它将被“释放”。

2
向量在push_back时会进行复制。由于指针只是“另一个变量”(但恰好指向内存),因此当您推送先前分配的整数指针时,将指针的值复制到向量中,从而可能导致悬空指针,因为将有两个指针指向内存中的同一位置。
在您的第一个示例中,您需要手动删除内存。我过去在处理图形类时使用的一种策略是像这样设置(由于正在工作和快速输入,因此已省略了大量内容):
class graph //quick-format
{
vector<node*> nodes;
add_node(node n)
{
  node *temp = new node; 
  *temp = n; 
  nodes.push_back(temp) 
}
~graph()
{ 
   for(int i = 0; i < nodes.size(); i++) 
      delete nodes[i]; 
}
};

作为警告,需要检查图的复制语义。目前情况下,它会导致删除先前释放的内存。优点是您始终可以拥有相同的节点集。买家须知,就像任何直接内存使用一样。
然而,如果您只是推送非指针变量,则没有可能从您的端口泄漏内存。可能向量会泄漏,但是……在工具成熟的现阶段,这几乎是不可能的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接