更好地理解堆栈和列表

Posted

技术标签:

【中文标题】更好地理解堆栈和列表【英文标题】:better understand of heap stack and list 【发布时间】:2012-07-29 03:09:09 【问题描述】:

有这个代码:

void set(list<Person*>* listP)
    Person timmy = Person(10);
    listP->push_back(&timmy);

int main()

    list<Person*> listP;
    set(&listP);
    Person* timmy  = listP.back();

如果我理解正确(请纠正我) timmy 是在堆栈上分配的,所以当我在 main 中使用它们时,我不能指望 timmy 的值。我对么?我需要像这样创建 timmy:

Person* timmy = new Person(10);

为了在堆上而不是在栈上创建,所以方法返回后不会被销毁?

谢谢

【问题讨论】:

【参考方案1】:
void set(list<Person*>* listP)
    Person timmy = Person(10); // create timmy on automatic storage (stack)
    listP->push_back(&timmy); //push timmy's address
 //timmy is destroyed. pushed address points to deallocated memory

是的,您需要使用Person* timmy = new Person(10); 在堆上分配。

void set(list<Person*>* listP)
    Person *timmy = new Person(10); // timmy is a pointer now
    listP->push_back(timmy); //push timmy's copy (copy of pointer)
 //timmy (pointer) is destroyed, but not the memory it points to

还喜欢使用smart_pointers,例如std::shared_ptrstd::unique_ptrboost 智能指针。它将简化内存管理和编写exception-safe 代码

【讨论】:

@user1495181:你的理解是对的,但结论不一定,你可以用list&lt;Person&gt;代替list&lt;Person*&gt;。这样可以避免这些问题。 感谢指正。是的,它会避免但会复制新实例。 @user1495181:当然,问题是......? 返回值优化很可能会在这里发挥作用。不确定 rvo 的确切条件是什么,但到目前为止我从来没有遇到过这些条件。复制 100k 元素两次可能比执行 100k 堆分配更快,除非您的元素非常重。 @user1495181:看看这个问题:***.com/questions/4809120/…【参考方案2】:

您的假设是正确的,但如果您使用 listPersons 代替,您没有必须在“堆”上创建 timmy

void set(list<Person>& listP)
    listP.push_back(Person(10));

极有可能不会在push_back (copy elision) 中制作额外的人员副本。在 C++11 中,即使没有省略复制,移动语义也可能发挥作用,并且复制代价高昂。

【讨论】:

您是在谈论 RVO 吗?它不是只用于大物体吗?见下面的讨论。谢谢! @user1495181 RVO 是复制省略的子集,适用于按值返回。所以它不适用于这个例子。我推测 push_back 只会做一个构造,但实际上它会加上一个复制构造。但是在 C++11 中,临时的 Person 会被移动复制。 @user1495181 我忘了说,RVO与返回对象的大小无关。 我测试看看 listP.push_back(Person(10)); dosnt 创建两个对象(在 c++11 中)并且确实如此。

以上是关于更好地理解堆栈和列表的主要内容,如果未能解决你的问题,请参考以下文章

更好地理解C#泛型

科技大数据:如何利用科普信息来更好地理解技术

更好地理解 PHP 和 SQL [关闭]

我试图更好地理解 `this` 的用法。这个例子很冗长,但它的目的是为了更好地理解[重复]

试图理解 C++ 中的堆栈和堆

读书笔记丨理解和学习事务,让你更好地融入云原生时代