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;
}