指针是一个变量,其中存放着地址。
首先来理解一下地址
如下:
int num = 5;
(0x0000 0005)
再来看指针:
int * p = #
int **pp = &p;
这里有两个概念需要理解一下:指向的内存空间,对应的内存空间。
例如:
num++:对num对应的内存空间的值+1;也就是5+1。
p++:对p对应的内存空间的值+1步长(这里p的存放的是num的地址,num是int型,int型为四字节,所以为0x1000+1步长-->0x1004。)
(*p)++:根据p对应的内存空间的地址,找到其对应的内存空间;对p指向的内存空间进行操作;即5+1。
再给出几个相应的式子帮助读者理解:
int **pp = &p;
(*pp)++: 0x1000-->0x1004;
(**pp)++: 5+1;
pp++: 0x2000-->0x2004;
num == *p == **pp == *(&num);
&num == p == *pp.
有人会问0x1000-->0x1001是什么意思,那我再举个例子来解释:
char * ptr = "hello world";
*ptr = 'L';//这里是指hello world中的h->L,因为这里是指针的首地址内容被换成L
ptr++;//这里的ptr存放的是字符串每一个字符的地址,每个字符是1字节,所以这里为0x4000-->0x4001。就是指ptr指针指向内容e的地址。
在编程时我们经常遇到段错误(Segment fault);
段错误:
所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gd tr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的 gdt表,后13位保存 相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向 的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起 始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。
通过上面的解释,段错误应该就是访问了不可访问的内存,这个内存区要么是不存在的,要么是受到系统保护的。
为什么会引起段错误:
往受到系统保护的内存地址写数据,有些内存是内核占用的或者是其他程序正在使用,为了保证系统正常工作,所以会受到系统的保护,而不能任意访问,这就是内存越界引起的段错误,其中野指针为常见的错误,下面我将谈谈我对野指针的理解。
野指针:随机指向内存中的一个地址,不一定有访问权限,导致内存泄漏(访问了已经释放的内存或没有权限的内存)。
解决野指针的简单方法:
定义指针变量的同时最好初始化为NULL,用完指针之后也将指针变量的值设置为NULL。