C语言字符串替换函数报错Process finished with exit code 138求助
问题分析与修复
导致SIGBUS错误的核心原因
- 写入只读内存:如果调用
censor时第一个参数传的是字符串字面量(比如censor("test string", "str", "XXX")),这类字符串在程序运行时被存放在只读数据段,尝试修改它会直接触发内存访问错误(SIGBUS/SIGSEGV)。必须确保第一个参数是可写的字符数组(比如char buf[] = "test string";)。 - 未处理替换串长度不匹配:你的代码默认
search和replace长度相同,但如果replace更长,写入时会超出原字符串的缓冲区边界;如果更短,不仅会留下原字符串的残留字符,越界写入的操作还会触发内存保护错误。 - 匹配逻辑疏漏:当部分匹配失败时(比如匹配了
search的前几个字符但后续不匹配),代码没有将t回溯到start的下一个位置,而是停在当前位置,可能导致漏匹配或逻辑异常。
修复后的代码示例
#include <stdbool.h> #include <string.h> void censor(char *s, const char *search, const char *replace) { size_t search_len = strlen(search); size_t replace_len = strlen(replace); char *t = s; // 处理搜索串为空的边界情况 if (search_len == 0) return; while (*t) { char *match_start = t; const char *s_ptr = search; // 检查当前位置是否匹配完整搜索串 while (*t && *s_ptr && *t == *s_ptr) { t++; s_ptr++; } // 确认完全匹配 if (*s_ptr == '\0') { // 替换串更长时,先移动后续字符腾出空间 if (replace_len > search_len) { size_t remaining_len = strlen(t) + 1; // 包含末尾的'\0' memmove(match_start + replace_len, t, remaining_len); } // 复制替换串到匹配位置 memcpy(match_start, replace, replace_len); // 替换串更短时,移动后续字符覆盖多余部分 if (replace_len < search_len) { size_t remaining_len = strlen(match_start + replace_len) + 1; memmove(match_start + replace_len, match_start + search_len, remaining_len); } // 跳过已替换的部分,继续查找下一个匹配 t = match_start + replace_len; } else { // 未匹配成功,移动到下一个字符 t = match_start + 1; } } }
关键修复点
- 用
strlen获取字符串长度,通过memmove安全处理内存重叠问题,适配替换串与搜索串长度不同的场景。 - 修正匹配逻辑,每次匹配失败后移动到下一个字符,避免漏匹配。
- 明确要求第一个参数必须是可写的字符数组,禁止传入字符串字面量。
内容的提问来源于stack exchange,提问作者Othmane
相关产品推荐
相关产品推荐

