<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>指针与内存 on Yun 的个人博客</title><link>https://yun7211.github.io/c-language/pointer-memory/</link><description>Recent content in 指针与内存 on Yun 的个人博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 18 May 2026 10:30:00 +0800</lastBuildDate><atom:link href="https://yun7211.github.io/c-language/pointer-memory/index.xml" rel="self" type="application/rss+xml"/><item><title>C 语言指针与所有权笔记</title><link>https://yun7211.github.io/c-language/pointer-memory/pointer-and-ownership/</link><pubDate>Mon, 18 May 2026 10:30:00 +0800</pubDate><guid>https://yun7211.github.io/c-language/pointer-memory/pointer-and-ownership/</guid><description>&lt;h2 id="指针问题的本质"&gt;指针问题的本质
&lt;/h2&gt;&lt;p&gt;C 语言不会替我们记录对象归谁所有、什么时候释放、还能不能访问。很多指针 bug 表面是野指针、重复释放或内存泄漏，背后都是所有权边界不清楚。&lt;/p&gt;
&lt;p&gt;写 C 代码时，可以主动给指针加上三类语义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;拥有：负责释放资源&lt;/li&gt;
&lt;li&gt;借用：只临时使用，不释放&lt;/li&gt;
&lt;li&gt;输出：函数负责写入结果&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="拥有型指针"&gt;拥有型指针
&lt;/h2&gt;&lt;p&gt;拥有型指针通常来自 &lt;code&gt;malloc&lt;/code&gt;、资源打开函数或创建函数。谁拥有它，谁就负责释放。&lt;/p&gt;
&lt;p&gt;命名上可以用 &lt;code&gt;create/free&lt;/code&gt;、&lt;code&gt;open/close&lt;/code&gt; 成对出现：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;buffer_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;buffer_destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这种接口比让调用者猜释放方式更稳。&lt;/p&gt;
&lt;h2 id="借用型指针"&gt;借用型指针
&lt;/h2&gt;&lt;p&gt;借用型指针不应该被释放，也不应该长期保存到超过对象生命周期的地方。&lt;/p&gt;
&lt;p&gt;函数参数里常见的 &lt;code&gt;const char *name&lt;/code&gt; 多数是借用。加上 &lt;code&gt;const&lt;/code&gt; 能明确函数不会修改传入内容。&lt;/p&gt;
&lt;h2 id="输出参数"&gt;输出参数
&lt;/h2&gt;&lt;p&gt;C 语言里常用输出参数返回多个结果。输出参数要说明是否允许为 &lt;code&gt;NULL&lt;/code&gt;，以及失败时是否会被修改。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sensor_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sensor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个接口至少需要约定：&lt;code&gt;dev&lt;/code&gt; 和 &lt;code&gt;value&lt;/code&gt; 是否能为空，返回非零时 &lt;code&gt;value&lt;/code&gt; 是否有效。&lt;/p&gt;
&lt;h2 id="小结"&gt;小结
&lt;/h2&gt;&lt;p&gt;指针本身只是地址。真正决定代码可靠性的，是所有权、生命周期和错误路径是否写清楚。&lt;/p&gt;</description></item></channel></rss>