时间:2021-05-19
当我在linux下写c语言的时候经常会遇到段错误.
所以就来细究一下.
段错误或段违规(segmentation violation)
查看Expert C Programming(Peter Van Der Linden) Pg.156
解释到段错误是由于内存管理单元(MMU)的异常所致,
而该异常则通常是由于解除引用一个未初始化或非法的指针引起.
就是指针正在引用一个并不位于你的地址空间中的地址.
书中的例子
复制代码 代码如下:
int *p = 0;
*p = 17;
这里显然 地址0 并不是你程序所在的地址空间 所能得到的
而我在试验的时候 几乎随便给个地址 都是段错误
这也很正常,在运行之前是很难知道系统给你分配的地址空间的.
于是我这样测试了一下
复制代码 代码如下:
int *p = 0;
int a = 7;
printf("a addr is %d\n",&a);
scanf("%ld",&p);
printf("%d",*p);
由于 变量a的地址肯定在系统给你的程序所分配的地址空间内
所以你按照a的地址 给p赋值
或者小数目的向上下移4的整数倍 都是没问题的
经测试 并无段错误
分析了一下原因
在linux中,当你malloc一段内存的时候 只是拿到了 这段内存的虚拟地址.而这段虚拟地址也名没有实质的映射到物理地址.
而只有当你使用这段内存的时候.系统会申请相应页表映射到相应的物理地址.
而*p直接随意指向一个虚拟地址 而这个虚拟地址并没有实际的物理地址与之映射.
这时候解引用会在MMU发出异常,返回到linux就会给用户报一个段错误.
而如果你定义1个int型变量 这个应该是一个栈地址 内核已经把它映射到一个实际的物理页
你在这个基础上小幅度上下偏移地址.相应的都应该有物理地址与之映射.
自然没有问题.
以上都是自己的个人理解.可能还有不足的地方.
欢迎大家交流指教!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C++中函数重载、覆盖与隐藏详解在C++语言中,函数扮演着很重要的角色,不管面向过程设计,还是基于对象设计;不管是面向对象编程,还是基于泛型编程,函数都可以随处
C语言中调用Swift函数实例详解在Apple官方的《UsingSwiftwithCocoaandObjectgive-C》一书中详细地介绍了如何在Object
C语言中const和C++中的const区别详解C++的const和C语言的#define都可以用来定义常量,二者是有区别的,const是有数据类型的常量,而宏
C语言中值传递和指针传递实例详解在C语言中,函数的参数和返回值的传递方式有两种:值传递和指针传递。值传递和指针传递初学者总会有一种朦胧的感觉,所以建议把指针传递
C语言中二级指针的实例详解用图说明示例代码:#includeintmain(intargc,constchar*argv[]){//inta=5;int*p1=