<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=Strcpy</id>
	<title>Strcpy - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=Strcpy"/>
	<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=Strcpy&amp;action=history"/>
	<updated>2026-07-15T18:13:43Z</updated>
	<subtitle>在这个wiki上该页的修订历史</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://arolstar52-zhtest.hf.space/index.php?title=Strcpy&amp;diff=257965&amp;oldid=prev</id>
		<title>60.248.27.175：​撤销60.248.27.175（讨论）的版本63676321</title>
		<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=Strcpy&amp;diff=257965&amp;oldid=prev"/>
		<updated>2021-01-11T10:12:21Z</updated>

		<summary type="html">&lt;p&gt;&lt;a href=&quot;/index.php?title=WP:UNDO&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;WP:UNDO（页面不存在）&quot;&gt;撤销&lt;/a&gt;&lt;a href=&quot;/wiki/Special:%E7%94%A8%E6%88%B7%E8%B4%A1%E7%8C%AE/60.248.27.175&quot; title=&quot;Special:用户贡献/60.248.27.175&quot;&gt;60.248.27.175&lt;/a&gt;（&lt;a href=&quot;/index.php?title=User_talk:60.248.27.175&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User talk:60.248.27.175（页面不存在）&quot;&gt;讨论&lt;/a&gt;）的版本63676321&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{noteTA&lt;br /&gt;
|G1=IT&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;lt;tt&amp;gt;Strcpy&amp;lt;/tt&amp;gt;&amp;#039;&amp;#039;&amp;#039; 是[[C語言]]的函式之一，來自 [[C標準函式庫|C語言標準函式庫]]，定義於 [[string.h]]，它可以複製以 null 為結束字元的記憶體區塊到另一個記憶體區塊內。由於[[String.h|字串在 C 語言]]不是首要的[[資料型態]]，而是以實作的方式來替代，在記憶體內以連續的[[位元組]]區塊組成，&amp;lt;tt&amp;gt;strcpy&amp;lt;/tt&amp;gt; 可以有效複製兩個配置在記憶體以[[指针 (信息学)|指標]]回傳的字串（字元指標或是字串指標）。&lt;br /&gt;
&lt;br /&gt;
函式原型如下：&amp;lt;ref&amp;gt;{{Cite web |url=http://www.cplusplus.com/reference/clibrary/cstring/strcpy.html |title=存档副本 |accessdate=2007-06-11 |archive-date=2007-06-10 |archive-url=https://web.archive.org/web/20070610093650/http://www.cplusplus.com/reference/clibrary/cstring/strcpy.html |dead-url=no }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
char *strcpy(char *destination, const char *source);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
傳回值是 &amp;lt;code&amp;gt;destination&amp;lt;/code&amp;gt; 字元陣列或是配置在記憶體的字元指標（或是字串指標）。&lt;br /&gt;
&lt;br /&gt;
== 使用方式與實作 ==&lt;br /&gt;
例如&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
char *str1 = malloc(LARGE_NUMBER);&lt;br /&gt;
char *str2 = malloc(LARGE_NUMBER);&lt;br /&gt;
&lt;br /&gt;
fgets(str1, LARGE_NUMBER, stdin);&lt;br /&gt;
strcpy(str2, str1); /* 這行程式碼類似 str2 &amp;quot;=&amp;quot; str1 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
前兩行程式碼是先配置記憶體，經由 &amp;lt;tt&amp;gt;malloc&amp;lt;/tt&amp;gt; 函式把配置完成的記憶體位址，傳回給 &amp;lt;tt&amp;gt;str1&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;str2&amp;lt;/tt&amp;gt;。到了下一行程式碼，指向 str1 的記憶體，會被使用者輸入的字串填滿。之後，複製 str1 字串到 str2 的記憶體區塊內。雖然 &amp;lt;tt&amp;gt;str2 = str1&amp;lt;/tt&amp;gt; 這個程式敘述可以出現類似的現象，但是它只能複製位址從 &amp;lt;tt&amp;gt;str1&amp;lt;/tt&amp;gt; 到 &amp;lt;tt&amp;gt;str2&amp;lt;/tt&amp;gt;，讓 &amp;lt;tt&amp;gt;str2&amp;lt;/tt&amp;gt; 指向 &amp;lt;tt&amp;gt;str1&amp;lt;/tt&amp;gt; 的記憶體，實際上也無法真正做到複製字串的動作。這就是 &amp;lt;tt&amp;gt;str1&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;str2&amp;lt;/tt&amp;gt; 兩個指標都指向相同的記憶體區塊位址。這相當於所謂的 {{tsl|en| Object copy| Object copy|shallow copy（淺複製）}}，因為 &amp;lt;tt&amp;gt;str2&amp;lt;/tt&amp;gt; 實際上沒有真正從 &amp;lt;tt&amp;gt;str1&amp;lt;/tt&amp;gt; 複製到字串，所以這兩個指標所指的其實都是同一個的字串。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;strcpy&amp;lt;/tt&amp;gt; 函式利用迴圈動作逐次完成複製字串中每一個字元。在GCC-4.8.0的testsuite中的实现如下：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
extern void abort (void);&lt;br /&gt;
extern int inside_main;&lt;br /&gt;
&lt;br /&gt;
__attribute__ ((__noinline__))&lt;br /&gt;
char *&lt;br /&gt;
strcpy (char *d, const char *s)&lt;br /&gt;
{&lt;br /&gt;
  char *r = d;&lt;br /&gt;
#if defined __OPTIMIZE__ &amp;amp;&amp;amp; !defined __OPTIMIZE_SIZE__&lt;br /&gt;
  if (inside_main)&lt;br /&gt;
    abort ();&lt;br /&gt;
#endif&lt;br /&gt;
  while ((*d++ = *s++));&lt;br /&gt;
  return r;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 緩衝區溢位 ==&lt;br /&gt;
必須注意使用 &amp;lt;tt&amp;gt;strcpy&amp;lt;/tt&amp;gt; 函式，因為如果來源字串的長度太長，當複製到目的緩衝區時，它會覆寫到連接目的緩衝區後方的記憶體，導致無法預期的結果。而且程式通常容易會出現[[記憶體區段錯誤|區段錯誤]]（也就是常見的例外現象），但是熟練的駭客會利用[[緩衝區溢位]]來破解進入作業系統（詳見[[電腦安全]]）。&lt;br /&gt;
&lt;br /&gt;
== Bounds checking variants ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;strncpy&amp;lt;/tt&amp;gt; 這個常見的 bounded variant 它的實作方式與 &amp;lt;tt&amp;gt;strcpy&amp;lt;/tt&amp;gt; 相類似，它只要複製指定的位元組個數，而且只要它接近指定的最大長度時，就會在目的緩衝區加上結束字元來結束複製動作。只要指定的位元組個數大於目的字串的長度，它就會因為緩衝區溢位而受到影響；然而，程式會自動假定來源字串是以 null 作為結束字元的字串，當來源字串的長度大於指定的長度時，它無法保證產生出來的結果是以 null 來作為結束字元的字串，它也可能出現[[記憶體區段錯誤|讀取例外]]的現象。&lt;br /&gt;
&lt;br /&gt;
=== strlcpy ===&lt;br /&gt;
{{main|:en:strlcpy}}&lt;br /&gt;
由 [[OpenBSD]] 的研發人員 {{lang|en|Todd C. Miller}} 和 [[西奧·德·若特|Theo de Raadt]] 兩人設計 &amp;lt;tt&amp;gt;[[strlcpy]]&amp;lt;/tt&amp;gt; 函式，通常視為是 &amp;lt;tt&amp;gt;strncpy&amp;lt;/tt&amp;gt; 安全版本。對於一些[[作業系統]]而言，這個函式會出現被掌控的問題，但是它已經被 [[glibc]] 維修人員給特別地刪除，所以在此建議使用 &amp;lt;tt&amp;gt;[[memcpy]]&amp;lt;/tt&amp;gt; 函式來替代。&amp;lt;ref name=&amp;quot;libc-alpha-discussion-1&amp;quot;&amp;gt;[http://sources.redhat.com/ml/libc-alpha/ libc-alpha mailing list] {{Wayback|url=http://sources.redhat.com/ml/libc-alpha/ |date=20070609043450 }}, selected messages from 8 Aug 2000 thread: [http://sources.redhat.com/ml/libc-alpha/2000-08/msg00053.html 53] {{Wayback|url=http://sources.redhat.com/ml/libc-alpha/2000-08/msg00053.html |date=20070221220315 }}, [http://sources.redhat.com/ml/libc-alpha/2000-08/msg00060.html 60] {{Wayback|url=http://sources.redhat.com/ml/libc-alpha/2000-08/msg00060.html |date=20071112132653 }}, [http://sources.redhat.com/ml/libc-alpha/2000-08/msg00061.html 61] {{Wayback|url=http://sources.redhat.com/ml/libc-alpha/2000-08/msg00061.html |date=20071111235826 }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== strcpy_s ===&lt;br /&gt;
&amp;lt;code&amp;gt;strcpy_s&amp;lt;/code&amp;gt; 函式是 &amp;lt;code&amp;gt;strcpy&amp;lt;/code&amp;gt; 的安全版本，屬於 ISO/IEC TR 24731 的標準， &amp;lt;ref&amp;gt;{{cite book |author= ISO/IEC |title= ISO/IEC WDTR 24731 Specification for Secure C Library Functions |year=2004 |publisher=國際標準化組織}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |url=https://buildsecurityin.us-cert.gov/daisy/bsi/articles/knowledge/coding/314.html |title=strcpy_s() and strcat_s() |accessdate=2006-08-12 |last=Plakosh |first=Daniel |publisher=Pearson Education, Inc. |archive-date=2006-09-23 |archive-url=https://web.archive.org/web/20060923080610/https://buildsecurityin.us-cert.gov/daisy/bsi/articles/knowledge/coding/314.html |dead-url=no }}&amp;lt;/ref&amp;gt;某些 C 函式庫支援這個函式，包含 Microsoft C Runtime Library（微軟 C 語言執行時期函式庫）。&amp;lt;ref&amp;gt;{{cite web|url=http://msdn2.microsoft.com/en-us/library/8ef0s5kh(d=ide).aspx |title= Security Enhancements in the CRT |accessdate= 2006-08-12 |author=Microsoft |publisher= MSDN}}&amp;lt;/ref&amp;gt; 它與 &amp;lt;code&amp;gt;strcpy&amp;lt;/code&amp;gt; 的不同在於，在它取得額外參數來決定目的緩衝區大小時，會因為發生溢位而出現錯誤，如此一來，就可以預防[[緩衝區溢位]]。由於 &amp;lt;code&amp;gt;strcpy_s&amp;lt;/code&amp;gt; 對於 C 語言來說是新的函式，所以沒有特別受到廣泛支援。&lt;br /&gt;
&lt;br /&gt;
反對Microsoft人士宣稱，這個函式連同其他Microsoft在其Runtime Library號稱對安全性所做的強化&amp;lt;ref&amp;gt;{{cite web |url=http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx |title=Security Enhancements in the CRT |accessdate=2008-09-16 |author=Microsoft |publisher=MSDN |archive-date=2008-09-13 |archive-url=https://web.archive.org/web/20080913103837/http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx |dead-url=no }}&amp;lt;/ref&amp;gt;皆為Microsoft試圖把開發人員鎖死在[[Microsoft Windows|視窗]]平台上的手段之一。&amp;lt;ref&amp;gt;{{cite web |url=http://www.informit.com/blogs/blog.aspx?uk=Theyre-at-it-again |title=They&amp;#039;re at it again |author=Danny Kalev |publisher=InformIT |access-date=2008-09-15 |archive-url=https://web.archive.org/web/20120115011928/http://www.informit.com/blogs/blog.aspx?uk=Theyre-at-it-again |archive-date=2012-01-15 |dead-url=yes }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |url=http://fsfoundry.org/codefreak/2008/09/15/security-crt-safer-than-standard-library/ |title=Security Enhanced CRT, Safer Than Standard Library? |deadurl=yes |archiveurl=https://web.archive.org/web/20080919005704/http://fsfoundry.org/codefreak/2008/09/15/security-crt-safer-than-standard-library/ |archivedate=2008-09-19 |accessdate=2008-09-15 }}&amp;lt;/ref&amp;gt;；雖然strcpy_s是屬於ISO/IEC TR 24731的標準而非Windows獨有的標準，且在本質上跟OpenBSD的strlcpy沒有差別。&lt;br /&gt;
&lt;br /&gt;
== 參考資料 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 外部連結 ==&lt;br /&gt;
&lt;br /&gt;
* [https://web.archive.org/web/20101126031738/http://www.openbsd.org/cgi-bin/man.cgi?query=strcpy&amp;amp;sektion=3 &amp;lt;code&amp;gt;strcpy(3)&amp;lt;/code&amp;gt;]：複製字串 – [[OpenBSD]] 函式庫函式[[手册页|說明手冊]]&lt;br /&gt;
&lt;br /&gt;
[[Category:C標準函式庫]]&lt;/div&gt;</summary>
		<author><name>60.248.27.175</name></author>
	</entry>
</feed>