多线程中 堆和栈的区别
2014-11-17 09:26 youxin 阅读(12558) 评论(0) 编辑 收藏 举报参考资料: 进程线程与栈 堆的关系(转)
一篇文章:
最初涉及多线程程序涉及的时候经常会出现一些令人难以思议的事情,用堆和栈分配一个变量可能在以后的执行中产生意想不到的结果,而这个结果的表现就是内存的非法被访问,导致内存的内容被更改。
理解这个现象的两个基本概念是:在一个进程的线程共享堆区,而进程中的线程各自维持自己堆栈。
另一运行机制就是如果声明一个成员变量 如 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线程在堆里分配的东西,所以不会发生误写。