C++ C++;将指针推回指针向量时获取临时地址

C++ C++;将指针推回指针向量时获取临时地址,c++,C++,我的代码中有一条警告: 警告:正在获取临时地址 我见过类似的问题,但它们没有回答我的具体问题 下面是我的代码所做的: vector<A*>* ex_A; ex_A->push_back( &A()); //I get this warning taking address of temporary vector*ex_A; ex_A->推回(&A())//我收到了这个临时地址的警告 这是未定义的行为吗 我以前确实有这个,这很好,但我不想担心从堆中删除内存 vec

我的代码中有一条警告:

警告:正在获取临时地址

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

下面是我的代码所做的:

vector<A*>* ex_A;

ex_A->push_back( &A());  //I get this warning taking address of temporary
vector*ex_A;
ex_A->推回(&A())//我收到了这个临时地址的警告
这是未定义的行为吗

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

vector<A*>* ex_A;

ex_A->push_back( new A());
vector*ex_A;
ex_A->推回(新A());
有人能给我解释一下这个警告是什么意思吗?

&A()
正在创建一个临时对象,它在完整表达式退出时自动销毁,而
new A()
在堆上创建一个新对象,它将一直存在,直到您使用
delete
手动销毁它


我应该补充一点,如果在
向量中存储分配了new的对象,并且该向量被破坏,那么存储在中的对象将不会被自动删除,因此将出现内存泄漏。您可以在您的程序上使用
valgrind--leak check=full my_compiled_program
来验证这一点,这通常是一个好主意。

a()
是一个临时变量,它将在语句末尾停止存在。当您获取它的地址时,您会得到一个很快就会失效的指针,下次尝试取消引用该指针时,您会得到未定义的行为。

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

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

ex_A->push_back(&A())


在这一行中,使用&you正在获取堆栈上指针的地址,一旦离开函数的作用域,该地址将不可用,因此您必须使用(新的a())来分配内存。

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


在第二种情况下,在堆上分配数据之后,数据在退出块后仍然“活着”,并且存储的指针指向有效数据。

< P>只要您在C++中工作,就必须查看内存…如果你想避免移动到夏普
我认为你需要决定谁将拥有你的向量中的项目——如果是向量,那么

ex_A->push_back(new A());
很好-但是在删除/完成该对象时,您只需注意删除该对象。
你不能

ex_A->push_back(&A());  

因为()位于堆上,将超出范围,并在当前范围结束时被删除。你想要的是让一个对象保持活动状态,而不必担心谁会删除它->你想要C#或Java来实现它。

谢谢!所以当它超出范围时,指针向量将指向一个悬空的指针?这个答案有两个问题:
a()
不会被删除,它会被破坏。这不会发生在块的出口,而是在完整表达式的末尾。当然,编译器发出警告是不对的;这应该是一个完全错误(根据标准)。嗯,这还不是未定义的行为。例如,您可以使用集合中的指针为随机数生成器设定种子。。。取消对任何指针的引用都是不好的。@Kerrek SB:不,即使读取这些指针的值也已经很有趣了。那是从哪里来的?我想这允许编译器完全省略临时变量的创建。@KerrekSB这个规则的动机是在一些古老的处理器中,地址和整数有单独的寄存器。其中一些会在加载地址时验证地址。在这个特定的场景中,我不认为内存真的有可能失效,但在其他场景中,存在这种可能性,标准的作者希望支持这些。今天,它仍然是未定义的行为,但我不会太担心它。您使用的是什么编译器?C++标准不允许将代码>和代码>应用到rValue.@ FrdodoFLUES是G++ 4.3。右值代表什么