[英]Returning array declared in function returns address of local variable in C?
我意識到,在函數調用中聲明的變量將被壓入堆棧,並且一旦函數到達其末尾,就會彈出聲明在堆棧上的局部變量並進入lala領域。
我不了解的是,如果我在函數中聲明了指針,則可以返回該指針而無需編譯器投訴,而對於數組,它確實會警告我。
這是我所指的示例:
char * getStringArray();
char * getStringPointer();
int main(){
char * temp1 = getStringPointer();
char * temp2 = getStringArray();
return 0;
}
char * getStringPointer(){
char * retString = "Fred";
return retString;
}
char * getStringArray(){
char retString[5] = {'F', 'r','e','d','\0'};
return retString;
}
在編譯期間,它將引發有關getStringArray()的“局部變量的返回地址”警告。 令我感到困惑的是,有人告訴我,僅通過名稱來引用數組(例如retString,no [])是指其在內存中的地址,就像指針一樣。
數組可以派上用場,很多時候我想在函數中使用數組並返回它,有什么快速的方法嗎?
正如我在評論中提到的那樣,這行得通嗎? 我猜malloc分配給堆,但它很好。 我仍然不清楚靜態數據和堆上的數據之間的區別。
char * getStringPointer(){
char * retString = (char *)malloc(sizeof(char)*4+1);
*(retString+0) = 'F';
*(retString+1) = 'r';
*(retString+2) = 'e';
*(retString+3) = 'd';
*(retString+4) = '\0';
return retString;
}
"Fred"
是一個未命名的全局變量,因此不會消失,並且返回指向它的指針是安全的。 但是getStringArray()
正在取消分配指針指向的所有內容。 就是這樣。
getStringPointer
在堆棧上分配一個指針,然后返回該指針,該指針指向可執行文件中某個位置的字符串“ Fred \\ 0”(不在堆棧上)。 getStringArray
為堆棧上的5個字符分配空間,將它們分配為'F''r''e''d'和'\\ 0',然后返回指向堆棧上的'F'地址的指針(因此函數返回后無效)。
有兩種方法圍着它,要么你可以malloc
為您的陣列一些空間上的堆,或者你可以做一個struct
,它包含一個適當大小的數組並返回。 您可以從函數中返回數值,指針和結構類型,但不能返回數組。
該數組無疑是指向堆棧本地內存的指針,因此編譯器可以確定這就是您要泄漏的內容,因此這就是您收到警告的原因。
只需將數組設置為static
,警告和生存期限制都將消失。
現在,該指針可能指向靜態對象或堆中的對象(在您的情況下,它實際上是靜態的),因此從僅查看一個表達式(無論您是否泄漏本地堆棧)並不明顯。 這就是為什么無論返回安全指針如何都不會返回警告的原因。 同樣, static
存儲類將保存您。 您的字符串常量恰好是靜態的,因此可以正常工作。
通過將static
修飾符添加到變量retString
並返回指針將解決此問題。
char * getStringArray(){
static char retString[5] = {'F', 'r','e','d','\0'};
return retString;
}
那將返回適當的值。
請注意,它仍然如何被當作指針,因為數組的第一個元素被衰減為T類型的指針,在這種情況下為char
。 這將使編譯器感到滿意,因為它與在源開始處定義的函數本身的原型聲明相匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.