C语言运行变位词检测函数报bus error,C++可正常执行
变位词检测代码在C中触发Bus Error问题
我有一段检测两个字符数组是否互为变位词的代码,在C环境下能正常运行,但放到C语言里运行时会出现bus error ./a.out错误。这段代码取自2005年的书籍,风格偏向C语言,我也基于经验写了更“现代”的C实现,不过仍有优化空间。我使用Apple Silicon设备,通过clang编译。
原始C代码(推测基于C03标准)
#include <iostream.h> #include <string.h> int anagram(char *x, char *y) { char *p; if (!*x && !*y) return 1; p = strchr(y, *x); if (!p) return 0; *p = NULL; strcat(y, p+1); return anagram(x+1, y); }
重构后的C++代码
#include <iostream> #include <string> using namespace std; int anagram(char *x, char *y) { char *p; if (!*x && !*y) return 1; p = strchr(y, *x); if (!p) return 0; *p = 0; strcat(y, p + 1); return anagram(x + 1, y); }
运行失败的C语言代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int anagram(char *x, char *y) { char *p; if (!*x && !*y) return 1; p = strchr(y, *x); if (!p) return 0; *p = 0; strcat(y, p + 1); return anagram(x + 1, y); }
C语言主函数
int main(int argc, char *argv[]) { char *x = "restful"; char *y = "esrftul"; printf("%d\n", anagram(x, y)); return EXIT_SUCCESS; }
问题原因
核心问题在于字符串字面量的可写性差异:
- 在C语言中,字符串字面量(如
"restful")被存储在只读数据段,程序尝试修改这部分内存时会触发未定义行为,Bus Error就是典型表现。代码里的*p = 0会直接修改y指向的字符串字面量,后续strcat操作也会写入只读区域,必然出错。 - 旧版C++(如C03)允许将字符串字面量赋值给非const的
char*,且很多编译器默认提供修改字符串字面量的扩展支持,所以C版本能运行,但这其实不符合现代C++标准,属于不规范写法。
修复方案
方案1:使用栈上可写字符数组
修改C的主函数,把字符串字面量复制到栈分配的字符数组中:
int main(int argc, char *argv[]) { char x[] = "restful"; char y[] = "esrftul"; printf("%d\n", anagram(x, y)); return EXIT_SUCCESS; }
char y[]会在栈上开辟足够容纳字符串的内存,并复制字面量内容,这部分内存是可写的。
方案2:动态分配可写内存
通过strdup函数复制字符串字面量到堆内存:
int main(int argc, char *argv[]) { char *x = strdup("restful"); char *y = strdup("esrftul"); printf("%d\n", anagram(x, y)); // 记得释放动态分配的内存 free(x); free(y); return EXIT_SUCCESS; }
额外提示
这段代码的逻辑本身存在隐患:strcat(y, p+1)会导致y的长度增加,但原数组的存储空间是固定的,容易出现缓冲区溢出,破坏内存结构。更安全高效的变位词检测方法是统计字符频率(用数组记录每个字符出现次数,对比两个字符串的统计结果),或者排序后直接比较字符串,避免修改原字符串和内存溢出风险。
内容的提问来源于stack exchange,提问作者nimitz
相关产品推荐
相关产品推荐

