基于C语言中段错误的问题详解
当我在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型变量 这个应该是一个栈地址 内核已经把它映射到一个实际的物理页
你在这个基础上小幅度上下偏移地址.相应的都应该有物理地址与之映射.
自然没有问题.
以上都是自己的个人理解.可能还有不足的地方.
欢迎大家交流指教!
相关推荐
-
C语言初学者代码中的常见错误与问题
问题开灯问题 有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3 个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推.一共有k个人,问最后有哪些灯开着?输入:n和k,输出开着的灯编号.k≤n≤1000 复制代码 代码如下: #include <stdio.h> #include <math.h> int main() { int a[1001],n,k,i,j; printf(&quo
-
详解C语言中scanf函数使用的一些注意点
(一)基本介绍 Scanf是系统自带的函数,声明包含在stdio.h文件中,因此要是有该函数,必须加载#include<stdio.h>头文件.当执行到scanf函数时,程序就暂停等待用户输入,该函数只接受变量的地址,格式为&变量名.是一个阻塞式的函数,2用户输入完毕后,则将值赋值给变量,至此函数调用完毕.敲回车键告知计算机键入完毕. (二)使用注意 ①. 使用scanf函数输入一个字符变量.Char a; scanf("%c",&a); ②. 同时输入多
-
C语言编程时常犯十八个错误小结
看着有错的程序,不知该如何改起,本人通过对C的学习,积累了一些C编程时常犯的错误,写给各位学员以供参考. 1.书写标识符时,忽略了大小写字母的区别. 复制代码 代码如下: main(){ int a=5; printf("%d",A);} 编译程序把a和A认为是两个不同的变量名,而显示出错信息.C认为大写字母和小写字母是两个不同的字符.习惯上,符号常量名用大写,变量名用小写表示,以增加可读性. 2.忽略了变量的类型,进行了不合法的运算. 复制代码 代码如下: main(){ float
-
深入理解C语言中编译相关的常见错误
1. /usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':(.text+0x18): undefined reference to `main'collect2: ld 返回 1Reason: no main function in source file2. to get compile options -I and -lpkg-config libe.g: pkg-confi
-
详解C语言中的错误报告errno与其相关应用方法
C语言标准库中的错误报告用法有三种形式. 1.errno errno在<errno.h>头文件中定义,如下 #ifndef errno extern int errno; #endif 外部变量errno保存库程序中实现定义的错误码,通常被定义为errno.h中以E开头的宏, 所有错误码都是正整数,如下例子 # define EDOM 33 /* Math argument out of domain of function. */ EDOM的意思是参数不在数学函数能接受的域中,稍后的例子中用
-
基础C语言编程时易犯错误有哪些
C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下"灵活的余地",但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误.看着有错的程序,不知该如何改起,通过对C的学习,积累了一些C编程时常犯的错误,以供参考. 1.书写标识符时,忽略了大小写字母的区别. main() { int a=5; printf("%d",A); } 编译程序把a和A认为是两个不同的变量名,而显示出错信息.C认为大写
-
C语言创建链表错误之通过指针参数申请动态内存实例分析
本文实例讲述了C语言创建链表中经典错误的通过指针参数申请动态内存,分享给大家供大家参考之用.具体实例如下: #include <stdio.h> #include <stdlib.h>// 用malloc要包含这个头文件 typedef struct node { int data; struct node* next;// 这个地方注意结构体变量的定义规则 } Node; void createLinklist(Node* pHder, int length) { int i =
-
C语言中返回错误信息的相关函数用法总结
C语言strerror()函数:返回错误原因的描述字符串 头文件: #include <string.h> 定义函数: char * strerror(int errnum); 函数说明:strerror()用来依参数errnum 的错误代码来查询其错误原因的描述字符串, 然后将该字符串指针返回. 返回值:返回描述错误原因的字符串指针. 范例: /* 显示错误代码0 至9 的错误原因描述 */ #include <string.h> main() { int i; for(i =
-
C语言调试手段:锁定错误的实现方法
在项目开发工程中,如果能确定哪个文件下的哪个函数下的哪行出错--即锁定错误,那该多好啊,该文章就是为此而作的.首先来了解一下文件默认的输出信息的函数吧:文件信息函数: 复制代码 代码如下: printf("line : %d\n", __LINE__); //当前行数printf("filename : %s\n", __FILE__); //当前文件名printf("function : %s\
-
C语言 volatile与const同时使用应注意的问题
const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好不要做太激进的优化. "const"含义是"请做为常量使用",而并非"放心吧,那肯定是个常量"."volatile"的含义是"请不要做没谱的优化,这个值可能变掉的",而并非"你可以修改这个值"
随机推荐
- Perl删除前导和拖尾空白(删除左右空格、空白字符)
- SQLserver 2008将数据导出到Sql脚本文件的方法
- Extjs407 getValue()和getRawValue()区别介绍
- Apache、Nginx 服务配置服务器端包含(SSI)
- 使用Java构造和解析Json数据的两种方法(详解二)
- Oracle两张表关联批量更新其中一张表的数据
- js实现select下拉框菜单
- Android中LinearLayout布局的常用属性总结
- 初识ThinkPHP控制器
- 关于ASP生成伪参数技巧 简洁实用的伪(僞)参数
- Sun认为C#不会替代Java
- Java Servlet上传图片到指定文件夹并显示图片
- MySQL常见错误有哪些_MySQL常见错误的快速解决方法
- 一个的简易文本编辑器源码
- Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
- javascript下过滤数组重复值的代码
- js jquery获取随机生成id的服务器控件的三种方法
- 5秒后跳转效果(setInterval/SetTimeOut)
- php安全开发 添加随机字符串验证,防止伪造跨站请求
- Spring MVC实现的登录拦截器代码分享