關於C語言中返回區域性指標變數
阿新 • • 發佈:2019-02-14
前言
寫這篇文章,是因為同學在leetcode上遇到了這樣一個錯誤:
- 題目:Two Sum
- 程式碼如下:
int* twoSum(int* nums, int numsSize, int target) { int i,j; int res[2]; /* 加上static之後正常執行 */ for (i=0; i<numsSize; i++) { for (j=i; j<numsSize; j++) { if (nums[i]+nums[j]==target) { res[0]=i; res[1]=j; break; } else { continue; } } } return res; }
- 執行時出現錯誤:
load of null pointer of type 'const int'
- Google之後發現,在宣告res[2]的時候加上static就可以正常執行。於是在《The C Programming Language》(P70,4.6 靜態變數)找到了相關內容:
用static限定外部變數與函式,可以將其後宣告的物件的作用域限定為被編譯原始檔的剩餘部分。該外部變數/函式除了對該所在的檔案可見外,其他檔案都無法訪問。
用static宣告內部變數,則該變數是某個特定函式的區域性變數,只能在該函式中使用。但它與自動變數不同的是,不管其所在函式是否被呼叫,它一直存在,而不像自動變數那樣,隨著所在函式的被呼叫和退出而存在和消失。換句話說,static型別的內部變數是一種只能在某個特定函式中使用但一直佔據儲存空間的變數。
分析上面的程式碼,函式返回了一個int型別的指標,但是報錯卻說是一個空指標。猜想是int res[2];的宣告導致res是一個自動變數的陣列指標,在退出該函式之後,res指標指向的記憶體被覆蓋,所以導致出錯。使用static進行宣告,可以保證res[2]不會因為函式的退出而消失。下面進行驗證。
驗證
平臺和工具
- Windows 10, Code::Blocks-16.01(mingw)
測試程式碼
#include <stdio.h> char *test1(void) { /* * 編譯時出現warning,執行時列印亂碼。 * char b[10] 是區域性變數,其存放在棧上,在函式執行完成就會被釋放。 * 而返回它存放的地址,此時已經是可能是個非法地址。 * 執行時列印亂碼,驗證了b[10]的記憶體被釋放。 */
輸出結果1:
test1:[w骾 A test1_ver2:abcde test2:` test3:abcdef
輸出結果2:
test1:[w詡? test1_ver2:abcde test2:` test3:abcdef