簡體   English   中英

如何為局部變量分配內存?

[英]how is memory allocated for local variables?

int* pi;
{
    int ar[1000000];
    int a =3,b=4;
    ar[3]=a*b
    pi=ar;
}//ar is destroyed
int ar2[]={5,6,7,8,9};
char* f="zcxzsdaaaaaaaaa";
std::cout<<pi[3]<<std::endl;// prints 12

我有兩個問題:

  1. 我聽說堆棧僅包含指向數據的指針。 如果是這樣,數據存儲在哪里? 例如char* a="bbbb"; 一個-放在堆棧上,“ bbbb”-其他位置。 哪里?

  2. 上面的代碼不能正常工作,意味着內存泄漏為1000000字節嗎? 變量ar被銷毀,但它指向的數據仍然存在。 而且我們不能在這里使用delete,因為ar不是動態分配的。

我聽說堆棧只包含指向數據的指針

你聽錯了 堆棧包含實際數據。 但是,如果該數據是指針,則存儲該數據。

如果是這樣,數據存儲在哪里? 例如char * a =“ bbbb”; 一個-放在堆棧上,“ bbbb”-其他位置。 哪里?

是的, a (指針)存儲在堆棧中。 實際的字符串"bbbb"存儲在可執行文件的固定部分中。

上面的代碼正常工作是否意味着1000000字節的內存泄漏? 變量ar被銷毀,但它指向的數據仍然存在。 而且由於ar不是動態分配的,因此我們不能在這里使用delete。

不,數組和指向數組的指針之間有區別。 ar (整個1000000字節)將存儲在堆棧中。 這與char const* ar = "... 1000000 chars ..."; ar在堆棧中時,它將自動“釋放”。

char const* a = "abcde"; // a is on the stack, pointing to "abcde" somewhere else.
char const b[6] = "abcde"; // *all* of b is on the stack, all 6 bytes

您的代碼中的問題是pi指向堆棧上不再存在的內容。 當您運行代碼時,它很可能在那里,因為“釋放”堆棧中的數據對非調試版本中的數據沒有任何作用。 這不是內存泄漏,您只有一個無效的指針。

最后說明:盡管基本上所有現代計算機體系結構都使用調用堆棧,但是C ++標准沒有提及它。 請注意,人們通常會說一個變量在棧上,但實際上可能只是存在於寄存器中。 例如,如果您編譯代碼,則變量pi可能永遠不會接觸堆棧,它可能會在函數有效期內一直停留在寄存器中,因為轉到堆棧的費用相對較高(與寄存器相比)。

ar也位於“堆棧上”。 從技術上講,您可以訪問它,因為內存仍被映射到地址空間(堆棧通常被映射為一個整體),並且可以看到與先前存儲的數據相同的數據,因為數據恰好沒有被覆蓋

這樣做是未定義的行為-您可以讀取覆蓋的數據,或者程序可能崩潰,或者包括感知到的正常操作在內,可能發生任何其他事情。 不要依靠這種行為,也不要在真實的代碼中嘗試這種行為(出於教育目的嘗試這種行為並詢問SO是可以的)。

此處沒有內存泄漏-函數退出時,堆棧內存會自動回收。

  1. 你聽錯了。 堆棧包含數據

  2. 不,整個數組超出范圍都可以視為“已銷毀”

1)所有變量都在堆棧中。 您不會自己分配內存。

2)沒有內存泄漏。 整個變量在堆棧上,並且在退出變量范圍時被破壞。 您不會使用new分配任何內容。

似乎並沒有真正解決內存泄漏的混亂。 在C ++中,您可以使用new關鍵字或malloc自己分配內存,這是內存泄漏值得關注的時候。 設計語言時,一旦超出范圍,將回收所有局部變量存儲空間。 每個人都指出ar位於pi {}的本地范圍內,因此一旦退出,這些內存位置就可以重用或輕易覆蓋,因此,如果您稍后將在代碼中打印pi的結果並像您一樣操作堆棧, {}范圍與pi可能是不同的值

暫無
暫無

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

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