临时对象存储在哪里?

Posted

技术标签:

【中文标题】临时对象存储在哪里?【英文标题】:Where are temporary object stored? 【发布时间】:2012-02-24 23:02:26 【问题描述】:

temporary objects 存储在动态(堆)内存中是真的吗?

【问题讨论】:

“IMO”?为什么那是你的意见?是什么让你这么认为? 【参考方案1】:

标准没有为它们强制要求任何内存区域(堆/堆栈),但它们就像局部变量“自动存储”,位于表达式的末尾(或绑定到 ref-to- 时更长) const) 它们被破坏。

大多数实现会将它们存储在堆栈中,就像局部变量一样。

编辑:

正如 James Kanze 所指出的:在临时的生命周期通过 ref-to-const 延长的情况下,它的存储位置在大多数实现中在某种程度上取决于该引用的存储位置。也就是说,在引用在静态存储中的情况下,临时也将是(刚刚在 gcc 上确认)。 (虽然恕我直言,虽然这在标准意义上仍然是暂时的,但在该词的直观英语意义上这是否是暂时的还是有争议的)

【讨论】:

-1 我会解释原因。即使未绑定到 const 引用,范围也不一定是表达式的结尾,但由于优化,它可以进一步扩展。看我的回答。 @LuchianGrigore:所以在您的示例中,在foo(); 返回后临时将存在?你能引用允许发生这种情况的标准吗? @Luchian Grigore 这里***.com/questions/9018778/… 说它应该是表达式的结尾,不是吗? @PlasmaHH 是的 - 12.2/2。另外,请参阅此问题***.com/questions/8451212/… 在少数情况下,它几乎可以肯定不在堆栈中。考虑像@​​987654324@ 这样的东西。在这种情况下(这是我唯一能想到的),临时数据可能与静态数据在同一个空间中。【参考方案2】:

这取决于他们的寿命。您在未绑定到本地静态引用以延长其生命周期的函数内部创建的临时对象很可能会在堆栈上创建。绑定到本地静态引用的临时文件很可能存储在程序二进制文件的 .data 部分中。同样适用于绑定到非本地引用的临时对象。在初始化非局部变量期间创建的临时变量(通过引用绑定的变量除外)应位于产生该非局部变量值的函数的堆栈上。

在展开期间表示抛出对象的异常对象也是临时对象。这些通常驻留在堆上。

【讨论】:

应该注意我的回答忽略了线程局部变量的存在。对此有经验的人应该说出来并澄清一下。 确实,虽然 OP 可能没有考虑到它们,但例外也是暂时的。以及 C++11 中的初始化器列表。至于线程局部变量,至少在 x86_64/linux 上,它们将存储在一个特殊的内存段中,借助 gs 段寄存器访问,每个线程的设置不同。 异常对象是临时的吗?或者完全是别的东西。 (在 §3.7 中,标准列出了四种“存储持续时间”:静态、线程、自动和动态。我经常对此感到疑惑:临时对象显然具有不同的持续时间,异常对象也是如此。) @James 在堆栈上为周围块的生命周期分配完整表达式临时对象的存储并不是不合理的,即使临时对象的实际生命周期可能要短得多。这是一个简单的实现模型,并且被 C++ 规范所允许。 12.2p5 末尾的示例讨论了具有静态存储持续时间的临时对象。不幸的是,静态存储持续时间有时会在规范中用于不打算匹配临时对象的情况(例如在“引用常量表达式”的定义中)。 委员会回复了您的缺陷报告,他们认为目前没有任何行动,因为规范中的任何内容似乎都不会在临时对象具有静态或自动存储持续时间时引起问题(可能是因为提到了“XXX 存储持续时间”的任何使用“变量”,它不会干扰临时变量,因为临时变量不是变量)。但是引用和地址常量表达式的定义是指“静态存储持续时间的对象”,它确实匹配临时对象。【参考方案3】:

这高度依赖于实现,但它们可能驻留在自动存储中。

请注意,由于优化,范围可能违反直觉。

以下内容:

class A

//...
;

//....

A foo()

   A a;
   return a;

这里,a 对象不一定只驻留在函数的范围内,但 RVO 可以发生。

此外,当通过值传递临时对象时,它可能不会立即被破坏。

void foo(A a);
//...

foo( A() );

这里,一个临时变量不一定只在那一行中是存活的,而是可以直接在方法的参数堆栈中构造。

【讨论】:

【参考方案4】:

大多数(如果不是全部)实现将它们存储在堆栈中(即自动存储),尽管我认为标准在任何地方都没有要求。这样做当然更容易,因为编译器必须保证临时变量的生命周期,并且所述生命周期可能包含对同一函数的递归调用,从而创建临时变量的另一个实例。

【讨论】:

以上是关于临时对象存储在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 导入和导出向导在使用临时表的存储过程中给出无效对象错误

临时表在哪里存储在 sql server 中?

在哪里存储 objectstore 和 vwsession 对象

我应该在哪里存储对象列表?

6.2临时表--Oracle模式对象

数据存储在哪里?