C语言替换字符数组指定字符报错:SIGBUS信号中断(退出码138)
问题原因与修复方案
错误根源
你传递给replaceCharWithChar的"Hello"是字符串字面量,这类数据在C语言中会被存储到程序的只读内存段(通常是.rodata)。你的函数里尝试通过*string = replacement修改这块只读内存,直接触发了内存访问违规,导致系统发送SIGBUS信号终止程序。
另外还有个小问题:replaceCharWithChar返回的是*string,也就是字符串末尾的'\0',但printf用%s格式符去打印这个返回值,会因为'\0'是空字符导致输出异常,这也是需要修正的点。
修复代码
方案1:使用可修改的字符数组
把字符串字面量复制到栈上的字符数组中,这样内存是可写的:
#include <stdio.h> // 修改返回值为char*,方便直接返回处理后的字符串 char* replaceCharWithChar(char *string, char toReplace, char replacement) { char *original = string; // 保存原始指针,最后返回 while(*string != '\0') { if(*string == toReplace) { *string = replacement; } string++; } return original; } int main() { // 把字符串字面量复制到可修改的字符数组 char str[] = "Hello"; printf("%s\n", replaceCharWithChar(str, 'H', 'T')); return 0; }
方案2:动态分配内存(适合不想修改原数组的场景)
如果不想修改原数据,可以动态分配内存存储修改后的字符串:
#include <stdio.h> #include <stdlib.h> #include <string.h> char* replaceCharWithChar(const char *string, char toReplace, char replacement) { // 分配足够内存,包括末尾的'\0' char *result = malloc(strlen(string) + 1); if (!result) return NULL; // 处理内存分配失败 char *ptr = result; while(*string != '\0') { *ptr = (*string == toReplace) ? replacement : *string; ptr++; string++; } *ptr = '\0'; // 手动添加字符串结束符 return result; } int main() { char *modified = replaceCharWithChar("Hello", 'H', 'T'); if (modified) { printf("%s\n", modified); free(modified); // 记得释放动态分配的内存 } return 0; }
关键说明
- 字符串字面量在C中本质是
const char*类型,即使你用char*去接收,也不能修改它的内容。 - 栈上的字符数组(比如
char str[] = "Hello")是可写的,因为它是把字面量的内容复制到了栈内存中。 - 动态分配的内存需要记得用
free释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Obscuritas
相关产品推荐
相关产品推荐

