【问题标题】: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);

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

谢谢

【问题讨论】:

    标签: c++ heap-memory


    【解决方案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:看看这个问题:stackoverflow.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 中)并且确实如此。
    猜你喜欢
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多