簡體   English   中英

在函數中聲明的返回數組返回C中局部變量的地址?

[英]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 這將使編譯器感到滿意,因為它與在源開始處定義的函數本身的原型聲明相匹配。

ideone樣品

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM