跳轉至內容

C 程式設計/string.h/strcat

來自華夏公益教科書,自由的教科書

在計算中,C 程式語言提供了一個名為 strcat 的庫函式,允許將一個記憶體塊附加到另一個記憶體塊。這兩個記憶體塊都需要以 null 結尾。由於在 C 中,字串不是一等公民資料型別,而是作為記憶體中 ASCII 位元組塊實現的,strcat將有效地將一個字串附加到另一個字串,給定兩個指向已分配記憶體塊的指標。該名稱strcat是“字串連線”的縮寫。strcat位於string.h標頭檔案中。

例如

char str1[14] = "Hello,";    /* The array has enough space for 'Hello,' plus " world!" plus a null terminator */
strcat(str1, " world!");
puts(str1);                 /* prints "Hello, world!" to stdout followed by a newline */

這是strcat:

char *
strcat(char *dest, const char *src)
{
    size_t i,j;
    for (i = 0; dest[i] != '\0'; i++)
        ;
    for (j = 0; src[j] != '\0'; j++)
        dest[i+j] = src[j];
    dest[i+j] = '\0';
    return dest;
}

的可能實現,它也可以根據其他字串庫函式定義

char *
strcat(char *dest, const char *src)
{
    strcpy(dest + strlen(dest), src);
    return dest;
}

邊界錯誤

[編輯 | 編輯原始碼]

strcat可能很危險,因為如果要附加的字串太長,無法放入目標緩衝區,它將覆蓋相鄰的記憶體,從而引發未定義的行為。通常,程式在發生這種情況時只會導致段錯誤,但熟練的攻擊者可以使用這種緩衝區溢位來入侵系統(參見計算機安全)。

邊界檢查變體

[編輯 | 編輯原始碼]

為了防止緩衝區溢位,strcat已經使用了幾個替代方案。它們都帶有一個額外的引數,該引數對目標緩衝區的長度進行編碼,並且不會寫入該緩衝區結束。如果提供了不正確的長度,它們仍然會導致緩衝區溢位。

char* strncat(char* dst, const char* src, size_t n);

最常見的邊界變體,strncat只附加指定數量的位元組,加上一個 NULL 位元組。這使得每個連線的字串都可以使用不超過它在緩衝區的“份額”,也許是為了建立表格。它不適合更常見的需要,即獲取適合緩衝區的連線字串的字首。為此,要傳遞的計數的正確值是bufferSize-strlen(buffer)-1。常見的錯誤是傳遞bufferSize, bufferSize-1bufferSize-strlen(buffer),這些都可能導致緩衝區溢位。

size_t strlcat(char* dst, const char* src, size_t size);

strlcat函式由 OpenBSD 開發者 Todd C. Miller 和 Theo de Raadt 建立,通常被認為是strncat更安全、更有用的版本。它將緩衝區的實際長度作為引數,並返回所需位元組數,允許呼叫者在可能的情況下重新分配緩衝區。它已移植到許多作業系統,但最值得注意的是被 glibc 維護者拒絕,他們建議 C 程式設計師需要跟蹤字串長度,並且“使用此函式只會導致其他錯誤”。[1]

errno_t strcat_s(char* dst, rsize_t size, const char* src);

strcat_s 函式,在 ISO/IEC TR 24731 中提出標準化。[2][3] 由 Microsoft C 執行時庫支援。[4] 以及其他一些 C 庫。如果源字串不適合,它將返回非零,並將緩衝區設定為空字串(如果原始字串未儲存在其他地方或呼叫者忽略返回結果,這是一個災難性的結果)。它也明確不受某些庫的支援,包括 GLibc 庫。[5] 微軟編譯器生成的警告訊息建議程式設計師更改strcatstrncat到這個函式,據一些人推測,這是微軟試圖將開發人員鎖定在其平臺上的行為。[6][7]

參考文獻

[編輯 | 編輯原始碼]
  1. libc-alpha 郵件列表,從 2000 年 8 月 8 日的主題中選取的郵件:536061
  2. ISO/IEC. ISO/IEC WDTR 24731 安全 C 庫函式規範. 國際標準化組織. 檢索於 2008-04-23.
  3. Plakosh, Daniel. "strcpy_s() 和 strcat_s()". Pearson Education, Inc. 檢索於 2006-08-12.
  4. Microsoft. "CRT 中的安全增強". MSDN. 檢索於 2008-09-16.
  5. "回覆:實現“C 庫的擴充套件”(ISO/IEC WG14 N1172)".
  6. Danny Kalev. "他們又來了". InformIT.
  7. "安全增強的 CRT,比標準庫更安全?".


[編輯 | 編輯原始碼]
華夏公益教科書