当推回指向指针向量的指针时,C ++获取临时地址

时间:2011-11-25 13:54:46

标签: c++

我的代码中收到警告:

警告:取临时的地址

我见过类似的问题,但他们没有回答我的具体问题。

这是我的代码正在做的事情:

vector<A*>* ex_A;

ex_A->push_back( &A());  //I get this warning taking address of temporary

这是未定义的行为吗?

之前我确实有这个,这很好,但我不想担心从堆中删除内存。

vector<A*>* ex_A;

ex_A->push_back( new A());

有人可以向我解释警告的含义吗?

6 个答案:

答案 0 :(得分:8)

&A()正在创建一个临时对象,它会在自动退出完整表达式时被破坏,而new A()会在堆上创建一个新对象,直到您使用{{1}手动销毁它}。

我应该补充一点,如果你在delete中存储用new分配的对象并且矢量被破坏,那么存储在里面的对象会被自动删除,因此你将有一个记忆泄漏。您可以在程序中使用vector<A*>来验证这一点,这通常是一个好主意。

答案 1 :(得分:2)

是的,这是未定义的行为。这段代码:

ex_A->push_back( &A());

将构造A的临时实例,然后将其地址添加到向量,然后销毁该实例并回收A占用的存储以供重用。向量内的指针将变为悬空 - 无法保证将在该地址进一步分配的内容,并且使用该地址是未定义的行为。

答案 2 :(得分:1)

A()是一个临时变量,将在语句结束时停止存在。当你获取它的地址时,你会得到一个很快就会失效的指针,下次你试图取消引用那个指针时,你会得到未定义的行为。

答案 3 :(得分:1)

考虑您创建的数据的范围。在第一种情况下,您在堆栈上创建一个对象,存储其地址,然后,当它超出范围时,将删除存储指针指向的数据。

在第二种情况下,在堆上进行分配,退出块后数据仍处于“活动状态”,并且存储的指针指向有效数据。

答案 4 :(得分:0)

ex_A-&gt; push_back(&amp; A());

在这一行中使用&amp;你正在把一个指针放在堆栈上,一旦你离开了你的功能范围,这个地址就不会有价值,所以你必须使用(新的A())分配内存。

答案 5 :(得分:0)

只要你在C ++中工作,你就必须要照顾记忆......如果你想避免那么急动! 我认为你需要对谁将拥有你的载体中的物品做出决定 - 如果它是矢量那么

ex_A->push_back(new A());

很好 - 但是你只需要在删除/完成后删除该对象 你不能

ex_A->push_back(&A());  

因为A()在堆上并且将超出范围并在当前范围结束时被删除。你想要的是让一个物体保持活着而不必担心会删除它 - &gt;你想要C#或Java。