C语言指针越界与野指针

野指针

1,指针变量未初始化

2,指针变量直接释放,没有置NULL

3,指针变量超越了其指向变量的作用范围,这种情况下,其所指向的变量已经不存在,而我们认为对指针进行操作依然指向该变量,这种情况危害最大。

如果对野指针进行了操作,那么很有可能造成不可预计的后果,因为你不知道野指针指向的内存区域的具体情况。

野指针不做过多的介绍,要通过养成良好的编程习惯,尽量避免野指针的存在。


指针越界

指针越界,发生越界访问也会造成严重的后果。


typedef struct x


char a, b;
struct x *p;
}x;


int main(void)
{
x c,*q;
c.p = &c;
q = &c;//假设q=&c为0x00000000
q = q + 1;此时q=0x00000008
printf("%p\n",&c.a);
printf("%p\n", &c.b);
printf("%p\n", c.p->p);
printf("%p\n", q);
printf("%p\n",q->p);//此时q=0x00000012,所打印的是0x00000012内存处保存的值
c.p = c.p + 1;
printf("%p\n", c.p);
printf("%p", c.p->p);//同上
getchar();
return 0;
}

结构体指针p发生了越界,我们想要打印的值变成了下一片8字节内存里面的值,如果对该内存进行访问,那么可能造成不可预知错误。

对于结构体指针进行+1操作,其值直接加上结构体的大小,指向下一片结构体内存。


那么结构体指针如何访问结构体内部的变量呢?

1、在知道结构体的情况下直接使用->对结构体内部变量进行访问,获得是变量的值,而不是变量的地址,这是显式访问。而->在内部汇编代码上实际上也是根据地址加上偏移来实现对内存的访问。

    printf("%p\n",q->a);

  00D13D43 8B 45 E4             mov         eax,dword ptr [q]  ;此处将q里面保存的结构体首地址传给eax
00D13D46 0F BE 08             movsx       ecx,byte ptr [eax]  ;此处取了q地址偏移一个字节出的内存地址
00D13D49 8B F4                mov         esi,esp  
00D13D4B 51                   push        ecx  
00D13D4C 68 B0 58 D1 00       push        0D158B0h  
00D13D51 FF 15 10 91 D1 00    call        dword ptr ds:[0D19110h]  ;printf()函数打印

2、通过结构体的首地址+偏移来访问结构体的内部变量,隐式访问。

     这里可以通过定义一个char类型的指针,因为char一般只有一个字节,访问起来方便。

通过指针对变量进行访问,实际上就是通过内存地址访问实现的,通过改变指针的值,从而实现了指向内存地址的改变。

指针

指针根据自身类型的不同,来决定自身的+1操作应该加上多少个字节,而不是只+1个字节。通常int 4个字节,char是1个字节,结构体是结构体的大小。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值