95 lines
9.3 KiB
HTML
95 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>生存期</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-c_language_lifetime skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">生存期</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="c.html">c</a>‎ | <a href="c-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>C 中每个<a href="c-language-object.html">对象</a>存在、拥有常地址、保有其最近一次存储值(除非其值不确定)<span class="t-rev-inl t-since-c99"><span>,对于 VLA 还有保有其大小</span> <span><span class="t-mark-rev t-since-c99">(C99 起)</span></span></span>的程序执行部分,被称作该对象的<i>生存期</i>。</p>
|
|
<p>对于声明有自动、静态及线程存储期的对象,生存期等于其<a href="c-language-storage_duration.html">存储期</a>(注意非 VLA 和 VLA 自动存储期的区别)。</p>
|
|
<p>对于拥有分配存储期的对象,其生存期始于分配函数的返回(包含从 <span class="t-lc"><a href="c-memory-realloc.html">realloc</a></span> 返回),终于 <span class="t-lc"><a href="c-memory-realloc.html">realloc</a></span> 或解分配函数的调用。注意因为分配的对象没有<a href="c-language-object.html">声明类型</a>,首次访问该对象所用的左值表达式类型会成为其<a href="c-language-object.html#.E6.9C.89.E6.95.88.E7.B1.BB.E5.9E.8B">有效类型</a>。</p>
|
|
<p>在生存期外访问对象是未定义行为。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">int</span><span class="sy2">*</span> foo<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span> a <span class="sy1">=</span> <span class="nu0">17</span><span class="sy4">;</span> <span class="co1">// a拥有自动存储期</span>
|
|
<span class="kw1">return</span> <span class="sy3">&</span>a<span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="co1">// a的生存期结束</span>
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> p <span class="sy1">=</span> foo<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// p 指向生存期结束后的对象(“悬垂指针”)</span>
|
|
<span class="kw4">int</span> n <span class="sy1">=</span> <span class="sy2">*</span>p<span class="sy4">;</span> <span class="co1">// 未定义行为</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>指向生存期结束的对象(或该对象后一位置)的指针拥有不确定值。</p>
|
|
<h3><span class="mw-headline" id=".E4.B8.B4.E6.97.B6.E7.94.9F.E5.AD.98.E6.9C.9F">临时生存期</span></h3>
|
|
<p><a href="c-language-value_category.html">非左值表达式</a>所指代的拥有数组成员的结构体和联合体对象(直接为其成员或为嵌套的结构体/联合体成员)拥有<i>临时生存期</i>。临时生存期始于求值指代该对象的表达式,终于<span class="t-rev-inl t-until-c11"><span>下一个<a href="c-language-eval_order.html">序列点</a></span> <span><span class="t-mark-rev t-until-c11">(C11 前)</span></span></span><span class="t-rev-inl t-since-c11"><span>包含它的完整表达式或完整声明器结束</span> <span><span class="t-mark-rev t-since-c11">(C11 起)</span></span></span>。</p>
|
|
<p>任何修改临时生存期对象的尝试会导致未定义行为。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw1">struct</span> T <span class="br0">{</span> <span class="kw4">double</span> a<span class="br0">[</span><span class="nu0">4</span><span class="br0">]</span><span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">struct</span> T f<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="br0">(</span><span class="kw1">struct</span> T<span class="br0">)</span><span class="br0">{</span><span class="nu16">3.15</span><span class="br0">}</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">double</span> g1<span class="br0">(</span><span class="kw4">double</span><span class="sy2">*</span> x<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="sy2">*</span>x<span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">void</span> g2<span class="br0">(</span><span class="kw4">double</span><span class="sy2">*</span> x<span class="br0">)</span> <span class="br0">{</span> <span class="sy2">*</span>x <span class="sy1">=</span> <span class="nu16">1.0</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">double</span> d <span class="sy1">=</span> g1<span class="br0">(</span>f<span class="br0">(</span><span class="br0">)</span>.<span class="me1">a</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// C99 : UB 访问生存期结束于 g1 开序列点的 a[0]</span>
|
|
<span class="co1">// C11 : OK , d 为 3.15</span>
|
|
g2<span class="br0">(</span>f<span class="br0">(</span><span class="br0">)</span>.<span class="me1">a</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// C99 : UB 修改生存期结束于序列点的 a[0]</span>
|
|
<span class="co1">// C11 : UB 试图修改临时对象</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-11">
|
|
<ul>
|
|
<li>C11 标准(ISO/IEC 9899:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.2.4 Storage durations of objects (p: 38-39)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<div class="t-ref-std-c99">
|
|
<ul>
|
|
<li>C99 标准(ISO/IEC 9899:1999):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.2.4 Storage durations of objects (p: 32)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<div class="t-ref-std-c89">
|
|
<ul>
|
|
<li>C89/C90 标准(ISO/IEC 9899:1990):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>3.1.2.4 Storage durations of objects</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin"></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|