You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言SIGBUS错误(退出码138)求助:字符串修改函数运行异常

错误原因与解决方法:SIGBUS信号触发的字符串字面量修改问题

错误原因

  • 你在main里传递的"abcdefghigk"是字符串字面量,C标准中这类字符串被存储在只读内存区域(程序的.rodata段),不允许被修改。
  • 你的squeeze函数里直接执行了 s[j++] = s[i]和s[j] = '\0'的写操作,属于违规修改只读内存的未定义行为,在M1架构的MacOS上触发了SIGBUS(总线错误),程序直接中断,因此没有任何输出。

两种修复方案

方案一:用可写的字符数组替代字符串字面量

把main里的字符串改成字符数组,这样内存是可写的,直接复用你原来的squeeze函数即可:

#include <stdio.h>

void squeeze(char s[], int c) {
    int i, j;
    for (i = j = 0; s[i] != '\0'; i++) {
        if (s[i] != c)
            s[j++] = s[i];
    }
    s[j] = '\0';
    printf("Converted: %s\n", s);
}

int main() {
    char str[] = "abcdefghigk"; // 字符数组,内存可写
    squeeze(str, 'c');
    return 0;
}

方案二:让函数返回新字符串(不修改原字符串)

如果不想改动原字符串,可以让函数动态分配内存生成新字符串,调用后记得释放内存避免泄漏:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* squeeze(const char s[], int c) {
    // 先计算新字符串的长度
    int new_len = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] != c) new_len++;
    }
    // 分配内存(多留1位存储终止符'\0')
    char* result = malloc(new_len + 1);
    if (!result) return NULL; // 处理内存分配失败的情况
    
    int j = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] != c)
            result[j++] = s[i];
    }
    result[j] = '\0';
    return result;
}

int main() {
    const char* str = "abcdefghigk";
    char* squeezed_str = squeeze(str, 'c');
    if (squeezed_str) {
        printf("Converted: %s\n", squeezed_str);
        free(squeezed_str); // 释放动态分配的内存
    }
    return 0;
}

额外提示

  • 以后声明字符串字面量时,尽量用const char*,编译器会帮你检查出试图修改只读内存的错误,提前规避问题。
  • 不同系统对修改只读内存的反应可能不同,有的会触发SIGSEGV(段错误),但核心原因都是触碰了不允许修改的内存区域。

内容的提问来源于stack exchange,提问作者ALAN WING

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:42:40