typedef struct st_dynamic_string {
char *str; // 字符串緩衝區首地址
size_t length; // 當前實際長度
size_t max_length; // 緩衝區最大容量
size_t alloc_increment; // 擴容步長
} DYNAMIC_STRING;
設計目標:記錄字符串實時狀態,支援高效動態擴容,避免頻繁 malloc/free 開銷。
my_bool init_dynamic_string(DYNAMIC_STRING *str,
const char *init_str,
size_t init_alloc,
size_t alloc_increment) {
if (!alloc_increment) alloc_increment = 128; // 默認步長 128 字節
size_t length = 1; // 至少容納 '\0'
if (init_str && (length = strlen(init_str) + 1) < init_alloc)
init_alloc = ((length + alloc_increment - 1) / alloc_increment) * alloc_increment;
if (!init_alloc) init_alloc = alloc_increment;
if (!(str->str = (char*) my_malloc(init_alloc, MYF(MY_WME))))
return TRUE; // 分配失敗
str->length = length - 1; // 不計終止符
if (init_str) memcpy(str->str, init_str, length);
str->max_length = init_alloc;
str->alloc_increment = alloc_increment;
return FALSE; // 成功
}
關鍵邏輯:根據初始字符串長度向上對齊 alloc_increment 倍數分配緩衝區,預留擴容空間。
my_bool dynstr_append_mem(DYNAMIC_STRING *str,
const char *append, size_t length) {
if (str->length + length >= str->max_length) { // 需擴容
size_t new_length = (str->length + length + str->alloc_increment) / str->alloc_increment;
new_length *= str->alloc_increment; // 對齊步長
char *new_ptr = (char*) my_realloc(str->str, new_length, MYF(MY_WME));
if (!new_ptr) return TRUE;
str->str = new_ptr;
str->max_length = new_length;
}
memcpy(str->str + str->length, append, length);
str->length += length;
str->str[str->length] = '\0'; // C 字符串安全終止
return FALSE;
}
擴容策略:按 alloc_increment 向上取整,減少 realloc 頻率,均攤 O(1) 追加複雜度。
my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n) {
str->length -= n;
str->str[str->length] = '\0';
return FALSE;
}
char *strcend(const char *s, char c) {
for (;;) {
if (*s == c) return (char*)s;
if (!*s++) return (char*)s - 1; // 到達末尾返回 '\0' 地址
}
}
my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size) {
if (!additional_size) return FALSE;
if (str->length + additional_size > str->max_length) {
str->max_length = ((str->length + additional_size + str->alloc_increment - 1)
/ str->alloc_increment) * str->alloc_increment;
if (!(str->str = (char*) my_realloc(str->str, str->max_length, MYF(MY_WME))))
return TRUE;
}
return FALSE;
}
功能:將多字符串拼接、轉義單引號、整體包裹單引號,產生可安全傳給 system() 的命令字符串。
輸入: ls -a'l → 輸出: 'ls -a\'l'
核心邏輯:遍歷可變參數列表,遇單引號插入 \' 轉義,首尾加引號。
realloc 失敗不修改原指針,調用者可檢測錯誤str[length] = '\0',兼容標準庫函數此結構廣泛用於 MySQL 內部 SQL 構建、錯誤信息格式化、日志生成等高頻字符串操作場景,是 C 語言動態字符串管理的經典範例。