注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

C++动态库中内存管理的一个BUG  

2014-11-04 20:15:57|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

C++动态库中内存管理的一个BUG

C#调用的C++动态库中,可以分配多大的内存?用NEW和用全局数组可以分配出多大的内存?这个都是问题。

分配一片大的内存,一般来说用下面的方法,当然,这种方法也是有缺点的,那就是内存是不可以移动的。相关内容看下面的博文。

WIN下的内存分配方式及相关概念”

http://fpcfjf.blog.163.com/blog/static/5546979320143902514825/

“理解程序内存”

http://fpcfjf.blog.163.com/blog/static/55469793201491913123487/

 

#define HANDLE_ERROR(x) if(!x) {HandleError(); return;}

 

void CHeapTestDlg::OnButtonHeapTest()

{

   const SIZE_T bytes = 0x40000000; // 1GB

 

   // create a private "growable" heap which has the maximum size

   // limited only by the available memory (see HeapCreate in MSDN for more details).

   HANDLE hHeap = ::HeapCreate(0, 0, 0);

   HANDLE_ERROR(hHeap);

 

   // alloc 1GB

   short* buffer = (short*)::HeapAlloc(hHeap, 0, bytes);

   HANDLE_ERROR(buffer);

   // ...enjoy of 1GB buffer.

   // ...

   //... free the buffer when is no more needed.

   BOOL bRet = ::HeapFree(hHeap, 0, buffer);

   HANDLE_ERROR(bRet);

 

   //... destroy the heap when is no more needed.

   bRet = ::HeapDestroy(hHeap);

   HANDLE_ERROR(bRet);

   // ...

}

 

void CHeapTestDlg::HandleError()

{

   DWORD dwError = ::GetLastError();

   // ... handle error (see this FAQ).

}

如果用VC的话,需要打开>2G的开关,project->peoperty->linker->system->Support Addresses Larger Than 2 Gigabytes (/LARGEADDRESSAWARE),一般来说,这个默认是自动打开的。

那么就有一个问题,在RELEASEDEBUG下,DLL中可以分配多大的内存空间,而在C#调用C++库中能分配多大呢?这个当然有一个前提,是在什么操作系统下,多少位。

http://www.tuicool.com/articles/myAfaq在这个网页上有相关的消息,他的32XP机器,3G内存,DEBUG下是695MRELEASE下是597M,但是如果换成C++调用C++的库则变成:985M。这样看来,在64位的8G情况下,可能会分配的更多。

遇到的问题就是在DEBUG下程序是OK的,RELEASE下是不对的,于是就怀疑是不是内存分配不出来,DEBUG和RELEASE两种情况下内存分配是不是不一样?而且又是在C#下调用C++的库,会不会同样也出现内存分配的不同的问题?当时就考虑到了上面的现象。

更大的问题是,在RELEASE的情况下调试,数据全部都是错误的,当时也没有想到在RELEASE下的调试方法:

一、很多时候需要在Release版本下调试程序,可以使用以下方法设置:

1、无效断点所在的项目和启动项目的设置:项目->属性->配置属性->C/C++->常规->调试信息格式,这里不能为『禁用』;

2、项目->属性->配置属性->链接器->调试->生成调试信息,这里设为『是』;

3C/C++->优化->优化选择『禁用』;

4、删除解决方案下的.ncb文件;

5、工具->选项->调试->『要求源文件与原始版本完成匹配』去掉勾;

6、最后在上述设置的情况下,重新编译整个解决方案;

二、经过试验,在VC2008下,新建一个项目的默认设置情况下,只需修改下面设置就可以调试release版本

1、在release模式下,修改 “项目->属性->配置属性->C/C++->优化->优化”  “禁用”,即可以调试。

后来还是在DEBUG下分析数据对比,才发现原来是指针越界,对数据的数量的关系理解有误,造成直接就溢出了。所以说不要轻信表面现象,还是要透过现象看到本质。

还是得注意细节。

 

 

 

  评论这张
 
阅读(385)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017