【C語言學習趣事】_函數返回後的地址_游離地址空間

來源:互聯網
上載者:User

  前些日子,在QQ群裡面,發現一些朋友在討論函數返回後,為什麼值可以傳遞和地址傳遞的情況;我也感到很好奇,

於是就跟了一下。

int*  sum(int x,int y){    int a;    a=x|y;        return &a;}

  很顯然這段代碼,存在一些問題;但是在VC2008中編譯一切正常,運行狀態也一切正常。

下面是我的測試代碼:

#include <stdio.h>int*  sum(int x,int y){    int a;    a=x+y;        return &a;}int getsum(int x,int y){    return x+y;}int main(void){    int *x;    int a;    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);        a=getsum(1,2);    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);    *x=100;    printf("*x=%d; x=%u\n",*x,x);    getchar();    return 0;}

運行結果如下所示:

  這個就是啟動並執行結果?但是為什麼呢?  而且兩次調用sum函數返回的地址完全一樣。

為了測試,我決定將代碼再進行異常改動。

#include <stdio.h>int*  sum(int x,int y){    int a;    a=x+y;        return &a;}int getsum(int x,int y){    int* p;    p=sum(10,2);    printf("*x=%d; x=%u\n",*p,p);    return *p;  }int main(void){    int *x;    int a;    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);        a=getsum(1,2);    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);    *x=100;    printf("*x=%d; x=%u\n",*x,x);            getchar();    return 0;}

  代碼依然堅挺的活著,而且順利的運行,如下所示,只是在getsum裡面調用sum函數,得到的地址與main函數中得到的不一樣。

  而且可以發現,無論怎麼調用,在main函數中調用sum,返回的地址一直是一樣的?  這是怎麼回事呢?

如果是這樣的話,那麼是否可以用這種方法動態分配地址呢?  是否可以我們free 一下看看。很不幸的是,失敗了?

  提示:可能是heap——棧——異常中斷了程式。

  為什麼會這樣呢?

原因可能是:

  1、C程式在啟動並執行過程中,其地址空間是固定的;雖然是可重新導向的,但是在“他”自己的線性空間,其地址空間是固定的,

也就是所函數調用的壓棧的空間,其棧基址是固定的。

  2、由於壓棧順序是一致的,而且每次壓棧時變數的offset是一定的。從左往右壓棧,或者從右往左壓棧都一樣會得到這個結果。

因此就出現了上面的情況。

  那麼怎樣說明這個過程的不正常呢? 雖然他看起來能編譯、連結和運行,結果也很正常。

#include <stdio.h>int *x;int*  sum(int x,int y){    int a;    a=x+y;        return &a;}void getsum(){    x=sum(10,2);        printf("*x=%d; x=%u\n",*x,x); //第二個輸出}int main(void){    int a;    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);  //第一個輸出        getsum();    printf("*x=%d; x=%u\n",*x,x);  //第三個輸出    *x=100;    printf("*x=%d; x=%u\n",*x,x);   //第四個輸出 
getchar(); return 0;}

  可以發現,第一個輸出,第二輸出的 *x的值一樣;  而第二個、第三個、第四個則是x的只一樣。這又是為什麼呢?

 我們在改一下:

 #include <stdio.h

int *x;int*  sum(int x,int y){    int a;    a=x+y;        return &a;}

void getsum(){ x=sum(10,2); printf("*x=%d; x=%u\n",*x,x); //第二個輸出}int main(void){ int a; x=sum(10,2); printf("*x=%d; x=%u\n",*x,x); //第一個輸出 getsum(); printf("*x=%d; x=%u\n",*x,x); //第三個輸出 *x=100; printf("*x=%d; x=%u\n",*x,x); //第四個輸出 x=sum(10,2); printf("*x=%d; x=%u\n",*x,x); //第五個輸出 getchar(); return 0;}

又或者這樣測試一下:

  

#include <stdio.h>int *x;int*  sum(int x,int y){    int a;    a=x+y;        return &a;}int*  sum1(int x,int y){    int a;    a=x+y;        return &a;}void getsum(){    x=sum(10,2);        printf("*x=%d; x=%u\n",*x,x); //第二個輸出}int main(void){    int a;    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);  //第一個輸出        getsum();    printf("*x=%d; x=%u\n",*x,x);  //第三個輸出    *x=100;    printf("*x=%d; x=%u\n",*x,x);   //第四個輸出     x=sum1(10,2);    printf("*x=%d; x=%u\n",*x,x);  //第五個輸出    getchar();    return 0;}

我們再改一下:

#include <stdio.h>int *x;int*  sum(int x,int y){    int a;    a=x+y;        return &a;}int*  sum1(int c,int d){    int a;    a=c+d;    *x=60;    return x;}void getsum(){    x=sum(10,2);        printf("*x=%d; x=%u\n",*x,x); //第二個輸出}int main(void){    int a;    x=sum(10,2);    printf("*x=%d; x=%u\n",*x,x);  //第一個輸出        getsum();    printf("*x=%d; x=%u\n",*x,x);  //第三個輸出    *x=100;    printf("*x=%d; x=%u\n",*x,x);   //第四個輸出     x=sum1(10,2);    printf("*x=%d; x=%u\n",*x,x);  //第五個輸出    getchar();    return 0;}

  輸出結果如下所示:

  發現x的地址可以一直引用。

  如果你要做一些壞事的話,這裡就是一個可以利用的地方。  可以通過這個全域的x變數,來修改傳遞給函數的參數值。

這個實驗就不做了。

  有興趣的可以試一下。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.