再谈让C++更像C#:C#内存泄露问题

前段时间写了一篇日志叫《让C++更像C#》,但我写的那段示例代码中的有关内存泄漏的问题当时我说先不管,其实是那时没有找到很好的解决方法。不好解决C#内存泄露的原因是,没有办法去判断一个指针到底是指向堆内存,还是指向栈内存(windows系统没有API来实现这样的功能)。当时google、baidu都搜遍了,没有找到解决办法。

现在,就进一步研究这个C#内存泄露的问题。

今天在看国外的一篇技术文章的时候,发现有人就在研究这个问题!他给出了一种解决办法。首先把他介绍,操作系统会为每一个系统中运行的线程分配一个数据结构叫做TIB(Thread Information Block)或者叫TEB(Thread Enviroment BLock)。里面记录了与某个线程相关的所有信息。当然包括线程相关的堆栈地址信息。而堆栈的栈顶与栈基址分别存放在FS寄存器的4与8位置处。所以他通过嵌入式汇编实现了判断指针是栈指针,还是堆指针的方法。代码如下:

 
 
 
  1. bool IsMemoryOnStack( LPVOID pVoid )
  2. {
  3.     LPVOID dwStackTop = 0;
  4.     LPVOID dwStackLowCurrent = 0;
  5.     __asm
  6.     {
  7.            mov EAX, FS:[4]
  8.            mov dwStackTop, eax
  9.             mov EAX, FS:[8]
  10.             mov dwStackLowCurrent, eax
  11.     }
  12.     if( pVoid < = dwStackTop && pVoid >= dwStackLowCurrent )
  13.     {
  14.         // The memory lie between the stack top and stack commited.
  15.         return true;
  16.     }
  17.     // Pointer dosen't point to the stack
  18.     return false;
  19. }

现在只需要把CTest可能引起内存泄漏的函数修改为如下,就可以解决问题了:

 
 
 
  1. CTest(CTest* & t) 
  2.  {
  3.   this->x=t->getX();
  4.   if(!IsMemoryOnStack(t))
  5.   {
  6.      delete t;
  7.      t=0;
  8.   }
  9.  }

这里使用指针引用的好处是在防止在释放了指针的内存后,用户继续访问指针的内存。

到此为止,问题全部解决了!印度的软件行业确实是挺牛比的!

这样,这个C#内存泄露问题就解决了。有关TIB的技术参考为:

http://www.microsoft.com/msj/archive/S2CE.aspx

网站名称:再谈让C++更像C#:C#内存泄露问题
本文来源:http://www.hantingmc.com/qtweb/news11/368911.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联