參考資料: 進程線程與棧 堆的關系(轉)
一篇文章:
最初涉及多線程程序涉及的時候經常會出現一些令人難以思議的事情,用堆和棧分配一個變量可能在以后的執行中產生意想不到的結果,而這個結果的表現就是內存的非法被訪問,導致內存的內容被更改。
理解這個現象的兩個基本概念是:在一個進程的線程共享堆區,而進程中的線程各自維持自己堆棧。
另一運行機制就是如果聲明一個成員變量 如 char Name[200],隨着這段代碼調用的結束,Name在棧區的地址被釋放,而如果是 char * Name = new char[200]; 情況則完全不同,除非顯示調用delete否則 Name指向的地址不會被釋放。
理解了線程對 堆棧 的可見性,和內存管理機制就能推測出筆者伊始提出的現象。
用一個 實例來深入理解這種機制。
在線程 1 中,
A ()
{
B();
C();
}
B()
{
棧 or 堆分配變量 V;
將V的地址插入 公共隊列;
}
線程 2 中:
D()
{
while(1)
{
處理公共隊列;
}
}
在B中如果用棧區 即采用臨時變量的機制分配聲明V和堆區,而者的結果是不同的。如果用棧區,如果變量地址為Am1-Am2這么大,退出B調用時候這段地址被釋放,C函數可能將這段內存改寫;這樣當D執行的時候,從內存Am1-Am2中讀取的內容就是被改過的了。
而如果用New(堆)分配,則不會出現那樣的情況,因為沒有顯示對用delete並且堆對於線程共享,即2線程可以看到1線程在堆里分配的東西,所以不會發生誤寫。