C语言 总线错误(bus error)与段错误(segmentation fault)

C 或 C++ 编程中,遇到错误时可能会看到“总线错误(bus error)”或“段错误(segmentation fault)”的提示。虽然它们都属于运行时错误,并且会导致程序崩溃,但它们是由不同的原因引起的。

1、总线错误(Bus Error)

总线错误通常发生在程序访问内存时,内存访问不符合硬件架构的要求。

int main() {
    int *ptr = (int *) 0x1234;  // 假设这个地址无效
    *ptr = 10;  // 尝试写入一个无效的内存地址,会导致总线错误
    return 0;
}

1)对齐错误

访问未按要求对齐的内存地址(例如,访问要求按 4 字节对齐的内存时,访问了一个 2 字节的地址)。

2)不存在的物理地址

访问一个物理内存中不存在的地址,通常是由于硬件或操作系统配置的原因。

3)内存映射错误

在使用内存映射文件(mmap)时,访问了无效的地址。

2、段错误(Segmentation Fault)

段错误是指程序尝试访问它没有权限的内存区域。通常是指程序访问了 虚拟地址空间中无效的段。常见原因可能是访问一个指向 NULL 的指针,访问了数组的非法位置,访问已释放的内存(悬空指针)。

#include <stdio.h>

int main() {
    int *ptr = NULL;
    *ptr = 10;  // 尝试解引用一个空指针,会导致段错误
    return 0;
}

3、总线错误与段错误的区别

特性

总线错误(Bus Error)

段错误(Segmentation Fault)

发生原因

内存访问不符合硬件要求

(如对齐错误、访问无效的物理地址等)

程序访问无权限的虚拟内存地址

(如空指针、越界等)

错误类型

由硬件引发,通常是无法处理的内存访问错误

操作系统触发的错误,通常由非法内存访问引起

常见场景

- 访问未对齐的内存地址

- 访问硬件地址

- 解引用空指针

- 数组越界

- 访问已释放内存

操作系统行为

操作系统会发送 SIGBUS 信号

操作系统会发送 SIGSEGV 信号

#include <stdio.h>

int main() {
    // 总线错误示例
    int *ptr1 = (int *)0x1;  // 指向一个不对齐的地址
    printf("总线错误示例:\n");
    printf("%d\n", *ptr1);  // 读取该地址时可能触发总线错误

    // 段错误示例
    int *ptr2 = NULL;  // 空指针
    printf("\n段错误示例:\n");
    printf("%d\n", *ptr2);  // 解引用空指针会触发段错误

    return 0;
}

推荐阅读
cjavapy编程之路首页