C C 中函式返回區域性變數的問題

2021-07-02 17:35:39 字數 2107 閱讀 6318

閱讀《c專家程式設計》中,描述乙個sun的pascal編譯器出現的bug——編譯器日期被破壞。這個bug點出c/c++中的函式返回區域性變數可能存在的問題:

1、如果函式返回的是區域性變數的值,程式不會出現問題;

2、如果函式返回的是區域性變數的指標(位址),可能會出現問題。

書中給出的**如下:

char * localized_time(char *filename)

然而,在實際的編譯(32bit-win7+vs2008環境)中,會出現問題,可能是windows和unix之間的差異,具體留後面討論。

書中講到:在c語言中,自動變數在堆疊中分配記憶體。當包含自動變數的函式或**塊退出時,它們所占用的記憶體便被**,它們的內容肯定會被下乙個所呼叫的函式覆蓋。這一切取決於堆疊中先前的自動變數位於何處,活動函式宣告了什麼變數,寫入了什麼內容等。原先自動變數位址的內容可能被立即覆蓋,也可能稍後才被覆蓋。

解決方案如下幾種:

1、返回乙個指向字串常量的指標。(此方案太過於侷限)

2、使用全域性宣告的陣列。

char *func()

缺點:<1>、任何人都有可能在任何時刻修改這個全域性陣列;

<2>、該函式的下一次呼叫也會覆蓋該陣列的內容;

<3>、浪費記憶體空間(尤其是陣列比較大的情況)。

3、使用靜態陣列。

char *func()

優點:可以防止任何人修改該陣列,只有擁有指向該陣列的指標的函式才能修改該靜態陣列(通過引數傳遞)。

<2>、浪費記憶體空間(尤其是陣列比較大的情況)。

4、顯示分配一些記憶體,儲存返回的值。

char *func()

優點:<1>、可以防止任何人修改該資料,且該函式在下次被呼叫不會覆蓋以前的返回值;

<2>、適用於多執行緒的**。

缺點:需要承擔記憶體管理的工作,容易產生記憶體洩漏。

5、出參的方式返回陣列,由呼叫者管理記憶體分配與**(推薦)

void func(char *result,int size)

buffer =malloc(size);

func(buffer,size);

...free(buffer);

最好在同一**塊同時進行「malloc」和「free」操作,遵循誰分配,誰釋放的原則。

好了,分享了作者的闡述,下面是我的通過編譯的測試**。

#include "stdafx.h"

#include #include #include char * localized_time(char *filename)

int main(void)

遇到兩個問題:

1、書中給出的**段:strftime(buffer,sizeof(buffer),"%a %b %e %t %y",tm_ptr);執行是產生崩潰。

原因是strftmie.c第832行丟擲異常,_asserte( ( "invalid format directive" , 0 ) );

結合strftmie.c中的源**及msdn。是因為strftime()函式沒有「%e和%t」,這裡可能是windows和unix的差異?沒有深究。

2、執行上述修改過的**後,發現:

<1>、呼叫函式可以列印出正確的返回值;

<2>、如果把buffer[120]改為buffer[90],呼叫函式

可以列印出正確返回值的一部分+亂碼;

<3>、如果把buffer[120]改為buffer[90],呼叫函式列印的結果為空;

<4>、注釋掉 「printf("strftime:%s\n",buffer);」,呼叫函式

列印的結果為亂碼。

這也印證了如果函式返回的是區域性變數的指標(位址),可能會出現問題。

zhaipillary

2015/05/21  於上海

函式返回區域性變數的問題

1.返回區域性變數的值 可以有兩種情況 返回區域性自動變數和區域性靜態變數,比如,int func 區域性變數temp儲存在棧中,函式返回時會自動複製乙份temp的copy給呼叫者,沒有問題。int func 區域性變數a儲存在靜態 全域性 儲存區中,從初始化後一直有效直到程式結束,僅分配一次記憶體...

函式返回區域性變數的問題

1.函式可以返回區域性變數 當函式的區域性變數作為函式的返回值時,其實是不知道是誰 是程式?會自動生成乙個變數的副本即拷貝作為函式的返回值,而原有的區域性變數將被銷毀。注意函式不可以返回區域性變數的位址或者某個指標,以為當函式執行完了 這裡改咋說 系統會 這塊位址,因此這個位址裡面 的東西也就沒有意...

函式返回區域性變數

一般的來說,函式是可以返回區域性變數的。區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址 指標 的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被...