[C++面試題]之指標與引用(2)

來源:互聯網
上載者:User
文章目錄
  • 1、下面這個程式測試會有什麼結果?
  • 5、C++中有了 malloc/free ,為什麼還需要 new/delete 呢?
1、下面這個程式測試會有什麼結果?
#include<iostream>using namespace std;void GetMemory(char *p,int num){p=(char *)malloc(sizeof(char) * num);}int main (){char *str = NULL;GetMemory(str,100);strcpy(str,"hello");return 0;}

解析:毛病出在函數GetMemory中,編譯器總是要為函數的每個參數製作臨時副本,在本例中,void GetMemory(char *p , int num)中的*p實際上是主函數中str的一個副本,而在函數GetMemory中只是把p所指向的記憶體位址改變了,但是str絲毫未變,因為函數GetMemory沒有傳回值,因此str並不指向p所申請的那段記憶體,所以函數GetMemory並不能輸出任何東西,如所示。事實上,每次執行一次GetMemory就會申請一塊記憶體,但是申請的記憶體卻不能有效釋放,結果是記憶體一直被獨佔,最終造成記憶體泄露。

 

如果一定要用指標去申請記憶體,那麼應該採用指向指標的指標,傳str 的地址給函數GetMemory。代碼如下:

#include<iostream>using namespace std;void GetMemory(char **p,int num){*p=(char *)malloc(sizeof(char) * num);}int main (){char *str = NULL;GetMemory(&str,100);strcpy(str,"hello");cout << *str << endl;cout << str << endl;cout << &str << endl;return 0;}

這樣的話程式就可以運行成功了,我們分別列印 *str 、 str 、 &str 可以發現,結果分別是 h 、 hello 、 0024FA80 。str就是字串的值;*str 是字串首字元,&str 就是字串的地址值。

當然也可以用函數傳回值來傳遞動態記憶體。這種方法更簡單,代碼如下:

#include<iostream>using namespace std;char *GetMemory(char *p,int num){p=(char *)malloc(sizeof(char) * num);return p;}int main (){char *str = NULL;str = GetMemory(str,100);strcpy(str,"hello");cout << *str << endl;cout << str << endl;cout << &str << endl;return 0;}

我們可以對這道題推而廣之,看一下整型變數是如何傳值的,代碼如下:

#include<iostream>using namespace std;void GetMemory1(int *num){*num=5;}int main (){int a;GetMemory1(&a);cout << a << endl;return 0;}

GetMemory1把 a 的地址傳了進來,*num 是地址裡的值,是 a 的副本.通過直接修改地址裡的值,不需要有傳回值,也把 a 給修改了,因為 a 所指向的地址的值發生了改變.

答案:

程式崩潰.因為GetMemory 並不能傳遞動態記憶體,主函數中的 str 一直是NULL。

 

2、寫出下面程式啟動並執行結果。
#include<iostream>using namespace std;int main (){int a[3];a[0]=0; a[1]=1; a[2]=2;int *p , *q;p=a;q=&a[2];cout << a[q-p] <<endl;}

      解析:本程式的結構如下:

(1)先聲明了一個整型數組a[3],然後分別給數組賦值。

(2)又聲明了兩個整型指標 p、q,但是並沒有定義這兩個指標所指向的地址。

(3)使整型指標 p 的地址指向 a(注意 a 就是a[0]),使整型指標 q 的地址指向 a[2]。

     可實際驗證程式如下:

#include<iostream>using namespace std;int main (){int a[3];a[0]=0; a[1]=1; a[2]=2;int *p , *q;p=a;cout << p <<endl;cout << *p <<endl;q=&a[2];cout << q <<endl;cout << *q <<endl;cout << a[q-p] <<endl;}

     上面的輸出結果分別是:

     002DFD24

     0

     002DFD2C

     2

     2

     2

     q 的實際地址是 002DFD2C,p 的實際地址是 002DFD24。 002DFD2C-002DFD24=0x08(十六進位減法),相差是 8。

     q-p的實際運算是(q的地址值(002DFD2C)- p的地址值(002DFD24))/sizeof(int),即結果為 2 。

答案:

運行結果是 2 。

 

3、請問下面的代碼的輸出結果是多少?
#include<iostream>using namespace std;class A{public:A(){m_a = 1;m_b = 2;}~A(){};void fun(){printf("%d%d",m_a,m_b);}private:int m_a;int m_b;};class B{public:B(){m_c=3;}~B();void fun(){printf("%d",m_c);}private:int m_c;};void main (){A a;B *p = (B *)(&a);p->fun();}

解析:首先可以肯定的是上面的代碼是非常槽糕的,無論是可讀性還是安全性都很差。寫這種代碼的人,按照Jarne Stroustrup(C++標誌化制定者)的說法,應該“斬立決”。

但是不得不說這也是一道很好考察你對記憶體位移的理解的題:

     B *p = (B *)(&a);

     這是一個野蠻的轉化,強制把 a 地址內容看成是一個B類對象,p 指向的是 a 類的記憶體空間。

     B類只有一個元素m_c 但是 A類的記憶體空間存放第一個元素的位置是 m_a, p指向的是對象的記憶體首地址,比如:0x22ff58,但p->fun()調用B::fun()來列印m_c時,編譯器對m_c的認識就是m_c距離對象的位移量是 0,於是列印了對象A首地址的位移量 0x22ff58+0變數值,即就是m_a的值1.

答案:

運行結果是:1

 

4、下面程式輸出結果是什嗎?
#include<iostream>using namespace std;class A{public:int m_a;A(){m_a = 1;}void print (){printf("%d",m_a);}};class B : public A{public:int m_a;B(){m_a = 2;}};int main (){B b;b.print();printf("%d\n",b.m_a);}

解析:B類中的 m_a 把 A 類中的 m_a 覆蓋掉了。在構造 B 類時,先調用 A 類的建構函式,所以 A 類中的 m_a 是1,b.print()列印的是 A 類中的    m_a ,而B類中的 m_a 是2。

答案:

12

 

5、C++中有了 malloc/free ,為什麼還需要 new/delete 呢?

答案:

(1)malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算子。它們都可用於申請動態記憶體和釋放記憶體。

(2)對於非內部資料類型的對象而言,只用malloc/free無法滿足動態對象的要求。對象在建立的同時要自動執行建構函式,對象在消亡之前要自動執行解構函式。由於malloc/free是庫函數而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和解構函式的任務強加於malloc/free。

(3)因此C++語言需要一個能完成動態記憶體分配和初始化工作的運算子new ,以及一個能完成清理與釋放記憶體工作的運算子delete。new/delete 不是庫函數而是運算子。

 

指標與引用部分算是寫完了,還有很多沒弄明白的,比如:指標函數、指向指標的指標也說得很少。可能上面的內容還有很多錯誤之處,歡迎指正…

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.