更好地理解堆栈和列表

时间:2012-07-31 11:00:07

标签: c++ heap

有这段代码:

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被分配在堆栈上,所以当我在主要使用它时,我不能指望timmy的值。我对么?我需要像这样创建timmy:

Person* timmy = new Person(10);

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

谢谢

2 个答案:

答案 0 :(得分:2)

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代码

答案 1 :(得分:2)

您的假设是正确的,但如果您使用timmy list s,则 无法在“堆”上创建Person代替:

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

极有可能在push_backcopy elision中不会有额外的副本。在C ++ 11中,即使副本没有被删除,移动语义也可以启动并进行昂贵的复制。