1) SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。
2) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。
非法映射 vs 非法获取、无定义(映射)
总线错误
- 对一个错误的起始地址进行解引用
由于进程的虚拟内存空间实际上是对物理地址的一个映射,操作系统和编译器会用内存对齐来做优化,通常就是4字节对齐,所以int,float这种类型的起始地址都是4的倍数,而short的起始地址是2的倍数,double的起始地址是8的倍数,假如此时对一个不是4倍数的地址a进行解引用 (int *) a,就可能会出现总线错误,这个出现的情况还要具体看是哪一种操作系统。总线错误一般不会出现,出现的情况多半是使用了指针的强制转换。
在计算机领域,总线错误(bus error)是一种硬件故障,为通知操作系统一个进程正尝试访问CPU无法访问的物理地址,即一个无效的地址总线地址,它由此得名。
在POSIX兼容平台上,总线错误通常导致发送SIGBUS信号到导致错误的进程。SIGBUS也可能因计算机检测到的任何常规设备故障引发。总线错误很少代表硬件存在物理损坏,而通常是因程序源代码中的程序错误引起。
总线错误有至少三种主要原因:
不存在的地址编辑
软件令CPU读写特定的物理内存地址时,CPU会将这个物理内存地址填入地址总线,并等待所有其他连接着CPU的硬件来认领并响应这个请求。当没有任何硬件响应CPU时,CPU会触发一个异常,表示整个计算机系统都无法识别上述请求的物理内存地址。需要注意的是,这里仅涉及到物理内存地址。如果访问一个未定义的虚拟内存地址,一般会产生一个段错误而不是总线错误,尽管对于MMU与CPU分离的计算机来说,CPU无法区分这两种情况。
未对齐的访问编辑
------------------越是喧嚣的世界,越需要宁静的思考------------------ 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。