对空指针赋值的问题 指针的指针 指针的指针和指针数组

对空指针赋值的问题(假如指针*p,这里所说的赋值不是p= XXX,而是*p=XXX)

首先说一下什么是指针:

假设 有语句 int a=10;
那么编译器就在内存中开辟1个整型单元存放变量a,我们假设这个整型单元在内存中的地址是 0x1000;那么内存0x1000单元中存放了数据10,每次我们访问a的时候,实际上都是访问的0x1000单元中的10.
现在定义:int *p;
              p=&a;
当编译器遇到语句int *p时,它也会在内存中给指针变量p分配一个内存单元,假设这个单元在内存的编址为0x1003;此时,0x1003中的值是不确定的,(因为我们没有给指针赋值),当编译器遇到了p=&a时,就会在0x1003单元中保存0x1000,请看,这就是说:(指针变量p代表的)内存单元0x1003存放了变量a的内存地址!用通俗的话说就是p指向了变量a。

p=NULL,就是说:内存单元0x1003不存放任何变量的内存地址。

看一下下面这段代码:

#include<iostream>
using namespace  std;
void main()
{
int *p=NULL;
*p=100;
cout<<*p;
}

执行的时候报错:指令引用的0x000000内存,该内存不能为written.

这里报错的原因是,因为指针p没有指向任何地址,所以为p所指空间赋值的时候,该空间不存在,所以执行的时候会报错。

指针的指针(转)

先看如下示例:

复制代码
 1  #include  < iostream >
 2  using   namespace  std;
 3 
 4  int  main()
 5  {
 6       int  a[ 5 =  { 1 2 3 4 5 };
 7       int   * =  a;
 8       int   ** point  =   & p;
 9 
10      cout  <<   " a =  "   <<  a  <<  endl
11           <<   " p =  "   <<  p  <<  endl
12           <<   " &p =  "   <<   & <<  endl
13           <<   " point =  "   <<  point  <<  endl
14           <<   " &point =  "   <<   & point  <<  endl;
15 
16       for  ( int  i  =   0 ; i  <   5 ; i ++ )
17      {
18          cout  <<   " &a[ "   <<  i  <<   " ] =  "   <<   & a[i]  <<  endl;
19      }
20       return   0 ;
21  }
复制代码

运行结果图如下:

我们先看下内存分配图:

从上图可以看出point指针中存放的是p指针的地址,而p指针中存放的是a[0]的地址。所以*point和p是一样的,前者是取point指针中存放的地址(0025F754)中的值,即取地址0025F754中存放的值(0025F760),而后者就是0025F760,所以两者是等价的。**point和a[0]是等价的,前者可以写成*p,*p是取p中存放的地址(0025F760)中的值,即地址0025F760中存放的值1。由上可以得出*point等于p, **point 等于 a[0]。通过上图可以清晰的对付诸如*point++等问题。


指针的指针和指针数组

看一下代码:

#include<iostream>

using namespacestd;

void main()

{

       int *m[3] = {0, 0, 0};

       int **pp=m;

       cout<<m<<endl;

       cout<<m+1<<endl;

       cout<<&m[0]<<endl;

       cout<<&m[1]<<endl;

       cout<<pp+1<<endl;

}     

运行结果是:

0012FF74

0012FF78

0012FF74

0012FF78

0012FF78

可以看出,指针的指针加1的含义是:指针的指针所保存的值加上指针的指针的类型大小。


再看下面的代码:

#include <iostream>
using namespace std;

void main()
{
int *m[3] = {0, 0, 0};
int **p;
p = m + 1;  //这里m+1的值是m[1]的地址


int a = 3, b = 4;
int *q = &a;
*p = q; //这里*p的值是p所保存的地址(m[1]的地址)的值(m[1]的值),此时变成q,即m[1]也等于q的值.
q=&b;
    
cout<<"**p="<<**p<<endl; //虽然q的值变了,但是*p=m[1],m[1]=q=&a,所以**p=*m[1]=a=3
cout<<"*q="<<*q<<endl;  //4


m[1] = &b;
cout<<"**p="<<**p<<endl;   //4
cout<<"*m[1]="<<*m[1]<<endl;//4
}

注意:当*p改变时,m[1]也改变了。

联系以上代码,再看看stl源码剖析中的代码段就比较容易理解了:

void*alloc<threads, inst>::refill(size_t n)

     {

         int nobjs = 20;

         char * chunk = chunk_alloc(n, nobjs);

         obj * volatile * my_free_list;

         obj * result;

         obj *current_obj, * next_obj;

         int i;

 

         if(1 == nobjs) return(chunk);

         my_free_list = free_list + FREELIST_INDEX(n);

         //如果没有上面这行代码,或是用my_free_list = NULL代替,那么在运行到:*my_free_list =next_obj = (obj *)(chunk + n);

          时,就会产生运行时错误:Run-Time Check Failure #3 - The variable'my_free_list' is being used without being initialized.

          因为要改变*my_free_list的值,实际上就是要改变my_free_list中保存的地址对应的值,而此刻my_free_list为空,也就谈不上它所指向的           空间的值了。//

         result = (obj*)chunk;


         *my_free_list =next_obj = (obj *)(chunk + n);

    

         for(i = 1; ; i++){

              current_obj= next_obj;

              next_obj =(obj *)((char *)next_obj+n);

              if(nobjs - 1 == i){

                   current_obj->free_list_link= 0;

                   break;

              }

              else{

                   current_obj->free_list_link= next_obj;

              }

         }

         return result;

     }




  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值