C++内存管理澄清
我是 c++ 新手。
我有一个 Rectangle 类。当我创建如下所示的 Rectangle 对象时:
Rectangle R1(10,10,90,20);
- R1 位于堆还是堆栈上?
- 如果我使用 new 运算符创建它,那么它只能在堆上吗?
(一般来说,在 C++ 中创建对象的正确方法是什么?)
据我了解,如果我在没有 new
的情况下创建它,则该对象位于堆栈上,不需要在最后删除其生命周期。如果使用 new 创建它,
Rectangle* R = new Rectangle(1,1,1,1);
它将被放置在堆上,并且需要使用 delete
取消分配。
I'm new to c++.
I've got a Rectangle
class. When I create a Rectangle
object like this:
Rectangle R1(10,10,90,20);
- Does R1 sit on the heap or stack?
- If I were to create it using the
new
operator, would only then it be on the heap?
(In general what would be the correct way to create an object in c++?)
To my understanding, if I create it without new
the object sits on the stack and does not need to be deleted at the end of its life time. And if do create it with new
Rectangle* R = new Rectangle(1,1,1,1);
it will be placed on the heap and would need to be de-allocated using delete
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这将创建一个具有“自动”持续时间的变量。当代码流退出作用域时它会自动销毁。如果它不在函数中,则意味着代码执行完成时。通常(但并非总是)它位于某种堆栈上。
这部分令人困惑:变量 R 是一个具有自动持续时间的指针(如上所示)。它指向一个具有“动态”持续时间的
矩形
。通常(但并非总是)动态对象位于某种堆上。仅当您使用delete R;
显式销毁矩形时,该矩形才会被销毁。这意味着如果函数结束并且没有R
的其他副本,则无法删除它,并且将保留在内存中直到程序结束。这称为内存泄漏。在 C++ 中,动态内存最好使用智能指针来处理,例如 std::unique_ptr,这样即使代码崩溃,您也不会意外忘记删除它。
This creates a variable with "automatic" duration. It is automatically destroyed when the code flow exits the scope. If it's not in a function, that means when the execution of your code completes. Usually (but not always) it sits on some sort of stack.
This part is confusing: The variable
R
is a pointer with automatic duration (like above). It points at anRectangle
with "dynamic" duration. Usually (but not always) the dynamic object sits on some sort of heap. The rectangle is destroyed only when you explicitly destroy it withdelete R;
. This means if the function ends and there is no other copy ofR
, it becomes impossible to delete, and will remain in memory until your program ends. This is called a memory leak.In C++, dynamic memory is best handled with a smart pointer, such as
std::unique_ptr
, so that you can't accidentally forget to delete it, even if the code is crashing.您所说的很多内容要么是实现细节,要么取决于上下文。考虑一下:
这里
r1
具有静态存储和静态(=永久)生命周期,而r2
具有自动存储和自动(=作用域)生命周期。也就是说,r1
在程序开始时构造并在程序结束时销毁(main
返回后),而r2
在声明时构造并在程序结束时销毁。其作用域的末尾(即本例中的函数体作用域)。指针
r3
指向动态存储和动态(=手动)生命周期的矩形
对象。对象*r3
在new
表达式中生效,并且只会在用户请求时通过匹配的delete
表达式(或也许是手动析构函数调用)。由于我们没有销毁它,这实际上是一个泄漏。关于
*r3
使用的内存一无所知,除了该内存是由静态成员函数Rectangle::operator new()
分配的> 如果存在,否则由全局分配函数::operator new
实现。全局版本的内存通常称为“自由存储”。(所有三个对象
r1
、r2
和*r3
被认为是相等的,因为r2
和*r3
被构造为r1
的副本。)当您考虑成员变量时,情况会变得更加有趣:
struct Foo { Rectangle r; };
。Lots of the things you say are either implementation details or dependent on the context. Consider this:
Here
r1
has static storage and static (= permanent) lifetime, whiler2
has automatic storage and automatic (= scoped) lifetime. That is,r1
constructed at program start and destroyed at the end (aftermain
returns), whiler2
is constructed at declaration and destroyed at the end of its scope (i.e. the function body scope in this case).The pointer
r3
points to aRectangle
object of dynamic storage and dynamic (= manual) lifetime. The object*r3
comes to life at thenew
expression, and it will only be destroyed at the user's request via a matchingdelete
expression (or perhaps a manual destructor call). Since we don't destroy it, this is in fact a leak.Nothing is known about the memory used by
*r3
, other than that this memory is allocated by the static member functionRectangle::operator new()
if it exists, or otherwise by the global allocation function::operator new
. The global version's memory is typically referred to as the "free store".(All three objects
r1
,r2
and*r3
are supposedly equal, sincer2
and*r3
are constructed as copies ofr1
.)The situation gets even more interesting when you consider member variables:
struct Foo { Rectangle r; };
.R1
是使用自动存储期限创建的。这意味着,实际上,它将分配在类似堆栈的结构上。你不必介意,“堆栈”只是方便且常见。您必须调用new
(或者malloc
,如果您出于某种愚蠢的原因确实想要这样做……则不要调用)来动态分配内存。见上文。
是的,您
新建
的任何内容都必须删除
。通常,一个班级会为您管理这个。以std::vector
为例。您在堆栈上分配向量,但内部数据(即 T 数组)是动态分配的。当向量
超出范围时,它会在其析构函数中删除[]
为您动态分配的数组,从而使您能够轻松地忽略底层内存管理细节。< /p>R1
is created with automatic storage duration. This means that, in practice, it will be allocated on a stack-like structure. It doesn't have to be mind you, a 'stack' is just convenient and common. You have to callnew
(ormalloc
if you really want to for some silly reason... don't) to allocate memory dynamically.See above.
Yes, anything you
new
you mustdelete
. Typically a class will manage this for you. Take for example anstd::vector<T>
. You allocate thevector
on the stack, but the internal data (i.e., an array of T) is allocated dynamically. When thevector
goes out of scope itdelete []
s the dynamically allocated array for you in it's destructor, allowing you to remain pleasantly ignorant of the underlying memory management details.