int split(const char *src, const char *delim, SplitResult *out) {
char *copy = strdup(src);
if (!copy) return 0;
out->count = 0;
out->strs = NULL;
char *token = strtok(copy, delim);
while (token) {
char **tmp = realloc(out->strs, (out->count + 1) * sizeof(char*));
if (!tmp) { free(copy); return 0; }
out->strs = tmp;
out->strs[out->count++] = token; // 直接指向 copy 內部
token = strtok(NULL, delim);
}
/* 注意:copy 必須保留到調用者釋放 strs 後再 free,
或在此 strdup 每個 token 獨立擁有內存 */
return 1;
}
上述代碼 strs[i] 指向 copy 內部,調用者必須先釋放 strs 數組,再釋放 copy。更安全的做法:
int main(void) {
SplitResult r;
if (split("a|b|c|d", "|", &r)) {
for (size_t i = 0; i < r.count; i++) puts(r.strs[i]);
for (size_t i = 0; i < r.count; i++) free(r.strs[i]);
free(r.strs);
}
return 0;
}
C 語言無內建分割函數,strtok + 動態數組是標準實現模式。關鍵在於內存所有權清晰:誰分配誰釋放,文檔化接口契約。生產代碼建議封裝 split_free(SplitResult*) 統一釋放。