博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VC内存溢出一例 –- 调用约定不一致
阅读量:5880 次
发布时间:2019-06-19

本文共 1206 字,大约阅读时间需要 4 分钟。

这个是网查的跟我在做图像分割realse相反的情况;

最近在写一个程序,调用了多个DLL,每个DLL代码都支持多线程,Debug的模式下基本调通了,但是在Release模式下,程序因为内存溢出而崩溃,中断在gs_report.c文件的298行位置(_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE),如下图:

     
     由于问题是出自某个DLL模块中,并且是多线程的,并且出现中断的断点无法回溯,很难直接定位到是哪个DLL模块的问题。在将一个一个模块被调用的代码注释后,大概确定了可能出问题的模块,以及可能的函数。由于是Release版本的问题,无法设置断点,只好用输出到Output窗口的方式调试,想进一步确定出现内存溢出的代码段。折腾了很长时间,一直没找到问题根源。
     网上搜索了一下,有人是Debug版本有这样的内存溢出错误,Release版本没有,是因为字符串填充的时候超过的申请的长度,和本例的情况不一样。开始我也觉得可能是哪个DLL库字符串操作问题,仔细检查了一些,没有发现问题。
     后来在测试一个作为参数传输到某个DLL中函数的字符串的时候,发现此字符串在被调用函数之后内容被改变了,而理论上被调用的函数是不改变此字符串的内容。调试了一下,发现此字符串在被调用的函数最后返回之前还是正常的,函数返回之后就不对了,也就是说函数退出之后的出栈操作有问题,不是按入栈完全相反的动作操作的。产生这个问题的原因有可能是函数的声明不对,也就是在DLL中的声明和在主程序中的声明不一致。检查了一下参数和返回值类型,是完全一致的。那会是哪不一样呢?
     DLL中的声明: EXPORTDLL unsigned int MyFunction(char * appname);
     主函数中的声明: typedef unsigned int (WINAPI *lpMyFunction)(char* appname);
     在VC中,EXPORTDLL定义为: #define EXPORTDLL extern “C” __declspec (dlexport); WINAPI定义为:#define WINAPI __stdcall ;回想起以前解决过的一些问题,在给回调函数传函数指针时,就为是用__stdcall还是__cdcall折腾过,所以估计这里可能是函数约定调用不一致导致的,正好和前面函数参数值被非法改变有关系。WINAPI这个调用约定是没法改的,那就修改DLL的函数。将DLL项目 Configuration Properties --> C/C++ --> Advanced --> Calling Convention设置从默认的__cdecl(/Gd)改为 __stdcall(/Gz),重新编译,重新运行,一切正常。

 

我的:

  恰好相反,release没问题,debug就出问题。

转载地址:http://yucix.baihongyu.com/

你可能感兴趣的文章
MySQL学习笔记20:数据备份与还原
查看>>
Spring 从零開始-03
查看>>
firefox如何卸载插件plugins和临时文件夹
查看>>
C++ for fun & test
查看>>
VUE -- 如何快速的写出一个Vue的icon组件?
查看>>
31.Node.js 常用工具 util
查看>>
服务器的svnserver修改密码
查看>>
利用 fdisk进行分区
查看>>
WPF 实现窗体拖动
查看>>
来自维基百科程序员Brandon Harris
查看>>
NULL不是数值
查看>>
CentOS 5 全功能WWW服务器搭建全教程
查看>>
30个优秀的后台管理界面设计案例分享
查看>>
scala111
查看>>
模块化服务规范——OSGI
查看>>
劣质代码评析——猜数字问题(上)
查看>>
纸上谈兵: 栈 (stack)
查看>>
Windows phone8 基础篇(三) 常用控件开发
查看>>
Oracle学习笔记之五,Oracle 11g的PL/SQL入门
查看>>
大叔手记(3):Windows Silverlight/Phone7/Mango开发学习系列教程
查看>>