2011-08-23 64 views
1

返回本地引用我不知道,如果這個問題已經問過(通過SOF搜查,但沒有找到答案)指針 - 在C++

我寫了一個LinkedList類和扭轉它的功能。功能如下,

struct LinkedList::element* LinkedList::recurrsiveReverseList(element* head){ 
    element* tempList; 
    if(head->next == NULL){ 
     return head; 
    }else{ 
     tempList = recurrsiveReverseList(head->next); 
     head->next->next = head; 
     head->next = NULL; 
     return tempList;   
    } 
    } 

這裏我聲明瞭一個局部指針變量,並對它做一些修改並將它返回給調用者。在C++中,當我在函數內部聲明局部變量時,範圍只存在於函數中。現在,當我從函數返回指針時,它是如何工作的?我能夠理解邏輯並得到結果(幸運的是),但我無法完全理解在這裏工作。

有人可以澄清我的疑問嗎?

+0

請注意,代碼片段中的第一個'struct'關鍵字是完全不必要的。 –

+1

不錯的功能。我會把'if(head == NULL || head-> next == NULL){' – sje397

+0

@seth卡內基:是的你是對的。該結構不是必需的。但是編譯器如何忽略它呢?我的意思是,當我返回一個對象/指針到一個類時,我沒有在函數定義中提及關鍵字'class'(如果我這樣做,是不是會拋出錯誤?)。但是如何忽略struct關鍵字呢? – Ajai

回答

2

tempList範圍終止,當你退出功能,但tempList是一個指向的內存塊,其範圍不結束那裏,因爲它是由new被分配無疑。以這種方式分配的內存直到您delete這一點纔有效,無論您進入或退出多少功能。

通過將指針傳遞迴調用方,它將其他位置的指針保留,您可以在其中使用它。

一個簡單的例子:

static char *fn (void) { 
    char *rv = new char[42]; 
    return rv; 
} 

int main (void) { 
    char *x = fn(); 
    delete [] x; 
    return 0; 
} 

在上面的代碼,它被聲明之後的rv範圍僅限於fn功能。

x的範圍在聲明後僅限於main函數。

但是通過new分配的內存就開始存在內fn繼續返回main後存在。通過將fn返回值分配給x,將初始存儲在rv中的所述​​存儲器的地址傳送到x

+0

這很有趣。所以你說如果我通過My​​Class * obj = new MyClass()在函數內部分配一個新對象,並且從該函數返回'obj',則obj將在程序中一直有效,直到有人刪除它爲止,僅僅因爲它是通過'new'分配的?如果我在裏面創建'MyClass obj'並且返回爲'return&obj',會不會保持不變? – SexyBeast

0

我假設您的鏈接列表節點分配在免費商店(即與new)。

當您使用new創建對象時,它將在免費商店中創建並存在,直到您致電delete爲止。您可以根據需要創建指向該位置的指針,它獨立於任何可能已經創建的函數調用。因此,在此函數中,您只是通過值將指針返回到免費商店中的該位置。指針只是一個數字,它是對象的地址,例如按值返回int

tl; dr:您明顯知道您可以通過值返回本地對象,因爲創建了副本。在這個函數中,它返回指向的指針的副本,指向免費存儲上的一個位置,該位置僅在用指向該存儲位置的指針調用delete時才被銷燬。

作爲另一個說明,你可能不應該返回一個指向新列表頭的指針,而是通過引用獲取一個指向列表頭的指針,並通過該列表改變列表,所以如果有人忘記指定他們的舊頭指針指向由recurrsiveReverseList返回的指針,事情不會混亂。

+0

不錯的建議,但我的想法是生成一個臨時反向列表,並將其交給用戶,而不影響現有列表(存儲在類內的列表)。 – Ajai

+0

@Ajai這將是非常低效的:)如果我是你(我不是這樣),我會提高效率的默認值,並使人們工作效率更低一點(因爲'newlist = oldlist; newlist.reverse )') –

+0

Hhhhmm有道理..用戶會認爲我正在逆轉當前,而在後面,我正在創建一個新列表並給用戶一個新的列表。我應該將這個函數從類中分離出來,或者讓函數記錄類中列表的變化。謝謝你的提示! – Ajai

0

tempList變量的使用範圍侷限於該方法內部,但它包含的內存地址就是返回的內存地址。 調用它的代碼將收到此內存地址,而不是變量tempList。

1

指針對象當您離開函數時,tempList將不復存在。但沒關係;您將返回(副本),該值存儲在對象中,而不是對象本身。這就像

int n = 42; 
return n; 

(返回一個局部變量的地址是什麼讓你陷入麻煩。)

2

不知道,如果別人這樣解釋它,但指針本身只不過是多了一些更,像... 0x12345678。該數字反過來解決了計算機內存中包含您正在查找的實際值的位置,即鏈接列表節點。

因此,當您返回該地址時,原始變量可能被銷燬。就像將街道地址複製到另一張紙上一樣,然後扔掉原來的紙張。在你有地址的房子還在那裏。

+0

不錯的例子。謝謝!可以提高投票率,但在我有15個聲望之前,SOF不會讓我。 – Ajai

+0

謝謝!這沒有問題〜 –