C 語言字串字面常數儲存在唯讀常數區,嘗試修改導致未定義行為(通常崩潰)。strdup 在堆上分配記憶體並複製字串,提供可修改的副本,是字串處理的安全基石。
char *s = "hello c"; // s 指向唯讀常數區
s[0] = 'a'; // 崩潰!Segmentation fault
char arr[] = "hello c"; // arr 在堆疊,內容為副本,可修改
arr[0] = 'a'; // OK
char *p = arr; // p 指向堆疊陣列
p[0] = 'b'; // OK,但修改的是 arr
#include <string.h> // POSIX 標準,非 C 標準庫
#include <stdlib.h> // free 需要
char *s = "hello c";
char *copy = strdup(s); // malloc + strcpy,返回堆上副本
copy[0] = 'a'; // 安全修改
copy[1] = 'b';
printf("原字串: %s\n", s); // hello c
printf("副本: %s\n", copy); // abllo c
free(copy); // 必須釋放!
char *strdup(const char *s) {
size_t len = strlen(s) + 1; // 含結束符
char *p = malloc(len);
if (p) memcpy(p, s, len);
return p; // 失敗返回 NULL
}
<string.h>_strdup,需 <string.h> 或 <stdlib.h>#ifdef _WIN32
#define strdup _strdup
#endif
strdup 正式納入 C23,未來可直接使用char *my_strdup(const char *s) {
if (!s) return NULL;
size_t len = strlen(s) + 1;
char *p = malloc(len);
if (p) strcpy(p, s);
return p;
}
| 函數 | 分配記憶體 | 複製長度 | 用途 |
|---|---|---|---|
strdup | 是 (malloc) | 整串含 \0 | 完整複製 |
strndup | 是 | 指定 n 字元 | 部分複製 (POSIX.1-2008) |
strcpy | 否 (需預先分配) | 整串 | 緩衝區複製 |
strncpy | 否 | 指定 n | 固定長度,不保證 \0 結尾 |
memcpy | 否 | 指定位元組 | 二進制複製,不看 \0 |
strdup 到堆free,避免洩漏NULL(OOM 情況)strndup 限制長度,防止惡意長字串耗盡記憶體