测试用例循环时出现Bus error:10——无额外缓冲区字符串去重故障排查
解决无额外缓冲区去重字符串时的Bus Error:10问题
嘿,我来帮你捋清楚这个问题的根源和解决办法~
首先,Bus Error:10在C语言里最常见的触发原因就是尝试修改只读内存区域,结合你的场景,单个测试用例正常、循环处理时出错,大概率是你在多测试用例循环里误用了字符串字面量导致的。
为啥单个测试用例没问题?
你写的char s[] = "aaabbb";是把字符串字面量的内容复制到了栈上的字符数组里,栈内存是可读写的,所以你的去重代码可以正常修改数组内容,不会触发错误。
循环处理时出错的核心原因
如果在循环里你用了类似char *s = "test case";这种声明方式,这里的"test case"是字符串字面量,它会被编译器放在只读数据段里。你的去重逻辑肯定需要修改字符串的内容(比如移动字符覆盖重复项),当代码试图修改只读内存时,操作系统就会抛出Bus Error:10来阻止你。
解决方案:确保处理可写的字符数组
不管是单个还是多个测试用例,一定要保证你处理的是可写内存区域的字符串,常见的做法有两种:
- 用栈上的二维字符数组存储所有测试用例
- 从输入读取测试用例时,读到栈上的字符缓冲区,或者用
malloc分配堆内存来存储
修正后的示例代码
#include <stdio.h> #include <string.h> // 无额外缓冲区的去重函数(仅用少量临时变量) void removeDuplicates(char *str) { if (str == NULL || *str == '\0') return; int tail = 1; // 指向去重后字符串的下一个写入位置 int len = strlen(str); for (int i = 1; i < len; i++) { int j; // 检查当前字符是否在已去重的部分出现过 for (j = 0; j < tail; j++) { if (str[i] == str[j]) break; } // 如果没出现过,就添加到去重后的字符串里 if (j == tail) { str[tail] = str[i]; tail++; } } // 加上字符串结束符 str[tail] = '\0'; } int main() { // 用可写的二维字符数组存储多个测试用例 char testCases[][50] = {"aaabbb", "abcabcabc", "aaaaa", "abcdxyz", "aabbccddee"}; int testCount = sizeof(testCases) / sizeof(testCases[0]); for (int i = 0; i < testCount; i++) { printf("原字符串: %s\n", testCases[i]); removeDuplicates(testCases[i]); printf("去重后: %s\n\n", testCases[i]); } // 如果是从标准输入读取测试用例,也要读到可写数组里 char inputBuffer[50]; printf("请输入测试字符串: "); fgets(inputBuffer, sizeof(inputBuffer), stdin); // 去掉fgets带的换行符 inputBuffer[strcspn(inputBuffer, "\n")] = '\0'; removeDuplicates(inputBuffer); printf("去重后: %s\n", inputBuffer); return 0; }
额外注意点
- 不要直接修改字符串字面量,永远用
char[]或者动态分配的内存来存储需要修改的字符串 - 如果你的测试用例长度不确定,记得用足够大的缓冲区,或者动态分配内存避免越界
内容的提问来源于stack exchange,提问作者David Stevens
相关产品推荐
相关产品推荐

