[英]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
我有兩個問題:
我聽說堆棧僅包含指向數據的指針。 如果是這樣,數據存儲在哪里? 例如char* a="bbbb";
一個-放在堆棧上,“ bbbb”-其他位置。 哪里?
上面的代碼不能正常工作,意味着內存泄漏為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)沒有內存泄漏。 整個變量在堆棧上,並且在退出變量范圍時被破壞。 您不會使用new
分配任何內容。
似乎並沒有真正解決內存泄漏的混亂。 在C ++中,您可以使用new關鍵字或malloc自己分配內存,這是內存泄漏值得關注的時候。 設計語言時,一旦超出范圍,將回收所有局部變量存儲空間。 每個人都指出ar位於pi {}的本地范圍內,因此一旦退出,這些內存位置就可以重用或輕易覆蓋,因此,如果您稍后將在代碼中打印pi的結果並像您一樣操作堆棧, {}范圍與pi可能是不同的值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.