對空指針賦值的問題 指針的指針 指針的指針和指針數組

對空指針賦值的問題(假如指針*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= {12345};
 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;

     }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章