首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言字串操作實戰:strcpy、strncpy、memcpy、memmove 四大複製函數差異與陷阱

     編輯:關於C

四大複製函數對比

函數原型複製單位結束條件重疊處理補 \0
strcpychar* strcpy(char* dest, const char* src)字元遇 \0未定義行為 (UB)是
strncpychar* strncpy(char* dest, const char* src, size_t n)字元n 字元或 \0UBsrc
memcpyvoid* memcpy(void* dest, const void* src, size_t n)位元組n 位元組UB否 (不關心 \0)
memmovevoid* memmove(void* dest, const void* src, size_t n)位元組n 位元組**安全支援重疊**否

核心陷阱與最佳實踐

1. strcpy 緩衝區溢位

char s1[8] = "str-1";
char s2[] = "str-2and123"; // 11 字元
strcpy(s1, s2); // 寫入 11 字元,溢出 s1,污染相鄰變數 s3

**禁用 strcpy**,改用 strncpy 或 snprintf。

2. strncpy 不自動補 \0 陷阱

strncpy(dest, src, sizeof(dest)-1);
dest[sizeof(dest)-1] = '\0'; // 手動保證結尾

3. 重疊記憶體只有 memmove 安全

char buf[] = "abcdefgh";
memmove(buf+2, buf, 4); // 正確: "ababcdgh"
memcpy(buf+2, buf, 4);  // UB: 可能 "ababcdgh" 或亂碼

memmove 內部自動判斷方向 (前向/後向複製) 避免覆蓋。

4. memcpy/memmove 適用任意型別

struct Data { int a; double b; };
struct Data src = {1, 2.0}, dest;
memcpy(&dest, &src, sizeof(src)); // 結構體整體複製

手寫實作核心邏輯

// strcpy
char *my_strcpy(char *d, const char *s) {
    char *ret = d;
    while ((*d++ = *s++));
    return ret;
}

// memmove (支援重疊)
void *my_memmove(void *d, const void *s, size_t n) {
    char *pd = d; const char *ps = s;
    if (pd > ps && pd < ps + n) { // 目的在來源後方且重疊 -> 從後向前複製
        pd += n; ps += n;
        while (n--) *--pd = *--ps;
    } else { // 否則從前向後
        while (n--) *pd++ = *ps++;
    }
    return d;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved