2013-05-07 23 views
0

我想我可能在這裏創建了內存泄漏:微妙的記憶泄漏,這是常見的做法?

void commandoptions(){ 
     cout<< "You have the following options: \n 1). Buy Something.\n 2).Check you balance. \n3). See what you have bought.\n4.) Leave the store.\n\n Enter a number to make your choice:"; 
     int input; 
     cin>>input; 
     if (input==1) buy(); 
     //Continue the list of options..... 
     else 
     commandoptions(); //MEMORY LEAK IF YOU DELETE THE ELSE STATEMENTS! 
    } 

inline void buy(){ 
    //buy something 
    commandoptions(); 
} 

比方說commandoptions剛剛exectued首次程序已經運行。用戶選擇'1',這意味着buy()子例程由commandoptions()子例程執行。

buy()執行後,它再次調用commandoptions()。

第一個命令選項()有沒有返回?或者我只是做了內存泄漏?

如果我做了一個子程序,除了自己調用它什麼也不做,它將導致一個stackoverflow,因爲該子程序的其他'週期'永遠不會退出。我在做/接近這麼做嗎?

請注意,我在購買時使用了inline關鍵字......這是否有所作爲?

我很高興地問我的教授,他似乎不可用。 :/

編輯:我不能相信它沒有想到要使用一個循環,但由於,我學到新的東西對我的詞彙!

+0

C++。這是一個班級。謝謝,忘記標記了。 – user1833028 2013-05-07 15:48:52

+0

我用你的語言標記了這個問題 – 2013-05-07 15:49:30

+3

我沒有看到泄漏,甚至沒有發現泄漏。 – 2013-05-07 15:50:52

回答

5

這基本上是一個沒有基本情況下的遞歸。所以,遞歸永遠不會結束(直到你用完堆棧空間)。

對於你想要做的,你最好使用循環,而不是遞歸。

並回答您的具體問題:

  • 沒有,commandoptions永遠不會返回。
  • 如果您使用一個非常廣泛的內存泄漏定義,那麼這是內存泄漏,因爲您正在創建堆棧框架而無需再次刪除它們。儘管(包括我),大多數人不會將其標記爲這樣。
  • 是的,你確實會最終導致堆棧溢出。
  • inline關鍵字在這方面沒有區別。
2

這不是memory leak,你這是無論什麼input值是commandoptions功能無限通話,這將導致堆棧崩潰。您的commandoptions功能需要一些退出點。

1

這裏沒有內存泄漏。發生什麼事情(至少它看起來是那樣,在你的代碼片段中)是你進入了一個無限循環。如果尾部調用優化未啓動或您的編譯器不支持,您可能會可能堆棧空間耗盡(儘管您的調用實際上處於尾部位置,但有點難以確定)。

5

內聯關鍵字不會導致內存泄漏。

如果這是您擁有的所有代碼,則不應該有內存泄漏。它看起來像你有無限遞歸。如果用戶鍵入'1',則在buy()內再次調用commandoptions()。假設他們在那個中輸入'1'。重複廣告無限,然後你最終崩潰,因爲堆棧太深。

即使用戶不輸入「1」,你還是再一次的commandoptions()內撥打commandoptions()的一樣,這將有完全相同的結果 - 崩潰,因爲無限遞歸的。

但是,我沒有看到內存泄漏的確切代碼。

+0

inline關鍵字是否會因爲它是子程序的一部分而導致它執行而阻止堆棧崩潰?這就是我現在想要知道的......不知道它的表現如何,確切地說...... – user1833028 2013-05-07 15:56:26

+0

簡短的回答:沒有。 – inetknght 2013-05-07 15:58:42

+0

長答案:'inline'關鍵字允許編譯器將該函數放入每次調用中。它通常不會在遞歸函數中工作,因爲函數會被添加到自身內部,同樣也是無限的 - 函數的長度是無限的,因爲它總是調用自己。 – inetknght 2013-05-07 15:59:40

7

內存泄漏是你已經分配使用new像這樣一些記憶:

char* memory = new char[100]; //allocate 100 bytes 

,然後你忘了,使用這種內存delete內存

delete[] memory; //return used memory back to system. 

後,如果您忘記了delete然後當你的程序正在運行時,你正在使用正在使用這個內存,並且不能被其他東西重用。看到內存是有限的資源,例如做這個數百萬次,沒有程序終止,會導致你沒有剩餘的內存使用。

這就是爲什麼我們自己清理。

在C++中,你會使用類似RAII的習慣用法來防止內存泄漏。

class RAII 
{ 
public: 
    RAII() { memory = new char[100]; } 
    ~RAII() { delete[] memory } 
    //other functions doing stuff 
private: 
    char* memory; 
}; 

現在你可以使用這個RAII類,所以

{ // some scope 
RAII r; // allocate some memory 

//do stuff with r 

} // end of scope destroys r and calls destructor, deleting memory 

您的代碼並不顯示任何內存分配,因此沒有可見的泄漏。

你的代碼似乎有無窮無盡的遞歸,沒有一個會終止遞歸的基本情況。

+0

如果內存是一個指向外部權限的指針,那麼你只需要調用內存中的delete [] ...... char類型的內存已經被該類破壞了,先生? – user1833028 2013-05-07 16:07:07

+0

他將幾個概念混合在一起。您只需在分配「新」的內存上調用刪除。但是,「刪除[]」與簡單的「刪除」略有不同。當您使用new分配數組時,只能調用「delete []」。而且你必須這樣做,在內存地址指針指向變化之前,或者在內存中的其他地方保留另一個引用。示例somePointer =新對象。 SomeTempPointer = somePOinter。您現在應該只對這些指針之一進行日曆刪除,並且其中一個可以超出範圍而不會造成泄漏。 – ChrisCM 2013-05-07 16:08:53

+0

聽起來很熟悉.... dang ....謝謝,我將不得不復習一下! ....我通常用直C ... – user1833028 2013-05-07 16:11:42