C語言函數返回類型爲指針時的一些問題

1.先看程序:

#include<stdio.h>

char  *returnStr()

{

           char  *p = “tigerjibo”;

           return  p;

}

int  main()

{

           char*str;

           str =returnStr();

           //str[0]=’T’;             則會引起錯誤,不能修改只讀數據段中的內容

           printf(“%s\n”,str);

           return0;

}

來分析下該程序。

(1)char  *p = “tigerjibo”。系統在棧上分配四個字節的空間存放p的數值。“tigerjibo”是字符常量,存放在只讀數據段內。指向完後,系統把”tigerjibo”的地址賦值給p。

(2)函數用return 把p的數值返回。該數值指向只讀數據段(該數據段內的數據是靜態的不會改變)。退出子函數後,系統把p的數值銷燬。但是p的數值已經通過return 返回。且只讀數據段中的內容不會被修改和回收(其輸於靜態區域)

(3)在主程序中把該地址又給了str。因此str指向了“tigerjbo”。

(4)該程序雖然能運行,擔又一個缺點,就是在程序中不能修改字符常常量中的數值。如果修改會引起段錯誤。


2.先看程序

#include<stdio.h>

char *returnStr()

{

           char  p[]=”tigerjibo”;

           return  p;

}

int  main()

{

           char  *str;

           str =returStr();

           printf(“%s\n”,str);

}

編譯該程序後,系統會提示如下警告:

function returns  address of local variable

(函數返回一個可變地址)

分析該錯誤:

1>”tigerjibo”是一個字符常量,存放在只讀數據段中,是不能被修改的。

2>char p[],是一個局部變量,當函數被調用時,在棧上開闢一個空間來存放數組P的內容。

3>char p[]=”tigerjibo”,該語句是把”tigerjibo”的值賦值給數值P,存放在數組p地址處。而不是把”tigerjibo”的地址賦值給數組p。因此,“tigerjibo”此時在系統中有一處備份,一個在只讀數據段中(不能修改,內容也不會被回收),一個在棧上存儲(可以修改起內容,但函數退出後,其棧上存儲的內容也會被回收)。

4>因此,當return p,返回了數組的首地址,但是當函數退出後,其棧上的內容也將被丟棄,局部變量的內存也被清空了,因此該數組首地址處的內容是一個可變的值。


3.先看一個程序:

#include<stdio.h>

char *returnStr()

{

           static  char p[]=”tigerjibo”;

           return  p;

}

int  main()

{

           char  *str;

           str =returnStr();

           str[0]=’T’;

           printf(“%s\n”,str);

}

此程序運行正確。

分析如下:

1>”tigerjibo”是一個字符常量,存放在只讀數據段中,是不能被修改的。

2>static char p[],是一個靜態局部變量,在讀寫數據段中開闢一個空間給p用來存放其數值。

3>static char p[]=”tigerjibo”,該語句是把”tigerjibo”的值賦值給數值P,存放在數組p地址處。而不是把”tigerjibo”的地址賦值給數組p。因此,“tigerjibo”此時在系統中有一處備份,一個在只讀數據段中(不能修改,內容也不會被回收),一個在讀寫數據段中存儲(可以修改其內容,當函數退出後,因其在讀寫數據段中存儲,起內容不會被丟棄)。

4>因此,當return p,返回了數組的首地址,但是當函數退出後,雖然棧上的內容都清除了,但是p地址是讀寫數據段中的地址,其上的內容不會被回收。


4.先看一個程序:

#include<stdio.h>

#include<string.h>

#include<strdlib.h>

void getmemory(char *p)

{

        p = (char *)malloc(100);

}

int  main()

{

      char  *str=NULL;

      getmemory(str);

      strcpy(str,”helloworld”);

      printf(“%s\n”,str);

}

編譯後錯誤:

段錯誤

分析:在主程序中,str地址爲空。在函數傳遞中將str的地址傳給了子函數中的指針p(是拷貝了一份),然後在字函數中給p在堆上申請了一個100字節的空間,並把首地址賦值給p。但是函數傳遞中,p值改變不會影響到主函數中str的值。因此,str的地址仍爲空。在strcpy中引用空指針會出現段錯誤。

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