2011-10-19 110 views
0

我是新来的C++。C++内存管理澄清

我有Rectangle类。当我创建了一个Rectangle对象是这样的:

Rectangle R1(10,10,90,20); 
  • 不R1冷眼堆或叠?
  • 如果我使用new运算符创建它,只会在堆上?

(一般会是什么,以C语言创建一个对象的正确方法+?)

据我了解,如果我没有new创建它的对象位于堆栈上,并不需要被删除在其生命周期结束时。如果做新

Rectangle* R = new Rectangle(1,1,1,1); 

它将被放置在堆上创建它,将需要使用delete被去分配。

+2

这是一个功课题吗? – SingleNegationElimination

+0

必须有这个副本。 –

+0

@TokenMacGuy我在做家务时遇到了这个问题 这不是它的一部分,它更像是一个普遍的想法。 –

回答

4
Rectangle R1(10,10,90,20); 

这会创建一个具有“自动”持续时间的变量。当代码流退出范围时它会自动销毁。如果它不在函数中,那意味着代码的执行完成。通常(但不总是)它位于某种堆栈上。

Rectangle* R = new Rectangle(1,1,1,1); 
Rectangle* P(new Rectangle(1,1,1,1)); //rarely used 

这部分是混乱:变量R是具有自动持续时间(如上文)的指针。它指向具有“动态”持续时间的Rectangle。通常(但不总是)动态对象位于某种堆上。只有在您明确销毁delete R;时,该矩形才会被销毁。这意味着如果功能结束并且没有其他的R副本,则无法删除,并且将保留在内存中,直到程序结束。这被称为内存泄漏。

在C++中,最好使用智能指针处理动态内存,如std::unique_ptr,这样即使代码崩溃,也不会意外忘记删除它。

std::unique_ptr<Rectangle> R(new Rectangle(1,1,1,1)); 
+0

请注意,如果'Rectangle *'超出范围(例如,函数调用返回)而没有调用'delete R',则将创建内存泄漏。 –

+0

谢谢,我不知道如果我需要删除R1 你已经说得很清楚,我没有 谢谢你的洞察力:) –

+0

我澄清了指针和堆上的矩形之间的区别。我希望。 –

0
  1. R1与自动存储持续时间创建。这意味着,在实践中,它将被分配在一个堆叠状结构中。它不必介意你,'堆栈'只是方便而且常见的。你必须拨打new(或malloc,如果你真的想出于某些愚蠢的原因......不要)动态分配内存。

  2. 见上。

  3. 是的,任何你new你必须delete。通常一个班级会为你管理这个。以std::vector<T>为例。您在堆栈上分配vector,但内部数据(即T的数组)是动态分配的。当vector超出范围时,delete []是您在其析构函数中为您动态分配的数组,允许您对基础内存管理细节保持愉悦无知。

1

你说的很多东西都是实现细节或依赖于上下文。这样考虑:

// file.cpp 

Rectangle r1(1,2,3,4); 

int main() 
{ 
    Rectangle r2 = r1; 
    Rectangle * r3 = new Rectangle(r1); 
} 

这里r1具有静态存储静态(=永久的)寿命,而r2具有自动存储自动(=作用域)寿命。也就是,r1在程序开始时构造并在最后销毁(在main返回后),而r2在声明中构造并在其作用域的末尾(即本例中的函数体范围)销毁。

指针r3指向动态存储动态(=手册)寿命Rectangle对象。对象*r3new表达式中生效,并且只会在用户请求时通过匹配的delete表达式(或者可能是手动析构函数调用)销毁对象*r3。由于我们不摧毁它,所以这实际上是泄漏

没有人知道关于内存通过*r3使用,比该内存由静态成员函数Rectangle::operator new()如果存在通过全球配置功能::operator new分配,或以其他方式等。全球版本的内存通常被称为“免费商店”。

(所有三个对象r1r2*r3是所谓平等,因为r2*r3构造为r1副本。)

的情况,当你考虑成员变量会变得更加有趣:struct Foo { Rectangle r; };