参考:首先,声明一点,凡是使用malloc之类命令动态申请的内存,必须进行释放操作,否则就会发生内存泄漏问题。

DLL中申请的内存释放,如果没有做过,很可能会认为是直接在调用程序中释放就可以了,其实不然,如果真那么做了,会发现,程序总是不明不白的当掉。那么,如何释放DLL中申请的动态内存呢?

首先,说明一点,对于DLL,采用了一种保护机制,那就是,DLL中的任何对象都是对外隐藏的,虽然我们通过传址调用的方式,在调用过DLL之后,可以访问DLL中动态申请的内存空间,但是,我们的调用程序并不能释放这个空间,原因就是因为它是对外隐藏的,由于这个原因,我们也只是获得了访问这类空间的权利,如果真的要释放的话,还得要被调用的DLL本向来完成,所以,我们在编写DLL的时候,如果发生了动态内存申请,并且,由于这些动态申请的内存会被调用的父进程程序访问,DLL结束的时候,并不能立即释放这些动态内存,那么,这时就需要我们同时编写一个专门用来释放这些动态内存的函数,和DLL编译到一起,然后,在父进程程序使用完这些动态内存空间后,再以传址的方式,调用这个释放函数,这样就可以将这些DLL中申请的动态内存空间释放掉了。

例:

DLL:

#include <stdio.h>

#include <string.h>

#include <malloc.h>

_declspec(dllexport)  void  testFunc(char **tmp)

{

*tmp = (char *)malloc(sizeof(char)*100);

memset(*tmp,'\0',100);

strcpy(*tmp,"susan");

}

_declspec(dllexport)  freeTestFuncMemory(char **tmp)

{

if(NULL != *tmp)

{

free(*tmp);

}

}

上述两个DLL要编译到一个LIB库里。

DLL调用:

int main(int argc,char **args)

{

char *employeeName = NULL;

testFunc(&employeeName);

printf("%s\n",employeeName );       /* 这里会输出 susan */

freeTestFuncMemory((&employeeName);

printf("%s\n",employeeName );        /* 这里会输出乱码 */

}

实际应用的时候,一定要注意,调用完分配内存的函数后,最好马上用三方变量将动态内存的值接出去,然后马上调用释放函数,否则如果在释放前又调用了其它DLL,那么再释放的时候就会出问题。我这次应用比较急,就没有再细查解决方法,哪位朋友发现方法了,麻烦可以给小弟留个言,谢谢。

这个例子不是很完整,不过原理是没有问题的,参照的话,请自行补充。

---------------------------------------------------------------------------------------------------------------------------------------

2016-10-26 0:45

张朋艺 pyZhangBIT2010@126.com

关于动态链接库中动态申请的内存区域如何传递到用户空间:刚开始尝试用指针,比如在dll中申请了一个char*的一串内存区域。

于是就有了下面的几个疑惑:

1. 比如在一个dll中的初始化函数中申请了一块char*的内存,之后函数返回,那么这块用malloc申请的内存是谁在维护?操作系统接管之后会不会被乱用掉???因为后续还会针对这块内存进行处理,不希望操作系统对这块内存进行额外的操作!

2. 刚开始使用同样的char*变量从dll的导出函数中将这块内存的地址传出,但是好像不对,于是考虑到了以前使用函数进行参数传递的时候,要想传递比如10个int型的数据,那么传递int*的变量就可以了。传递的必须是地址,所以,对于char*的一篇内存,我要传递过去的话,实际上是应该使用char**,就是指针的指针,而不能使用char*。如果使用char*进行传递的话,比如在User定义了一个char* pData变量,该变量作为参数送入了DLL的导出函数中,然后该函数中对char* pData进行了赋值,赋值为DLL中动态申请的char*的首地址,那么实际上char*
pData的值并没有发生改变。对这个变量pData赋值,是没有用的,你得是对这个变量的存储地址进行赋值才有效,所以,必须对这个pData的存储地址进行赋值。还是有点乱,重新捋一下:对于传递好几个int型的变量的时候,传递的是int型变量的地址,通过操作它们的内存地址以达到传递int型变量的目的。操作地址赋值,就是往存储这个变量的地址上写入要传递的变量,才能达到真的传递参数的目的;那么说到这个char*的内存区域pMem,pMem实际上就等于这块内存空间的起始地址,那么我希望传递这个地址,是不是得通过(char*)*ppMem的地址上的内容才能传递呢?即*ppMem
= pMem即可,这个时候使用*ppMem就可以访问到这片内存区域了,具体的就是(*ppMem)[0,1,2....]。

目前对于第一个疑惑,还是不太清楚,DLL中malloc的内存,在函数返回后,操作系统会对这片内存如何处理?会不会有别的东西乱入这篇内存区域,导致我后续使用这篇内存区域的时候出现难以察觉的问题。

------

2016-10-26 1:12

张朋艺 pyZhangBIT2010@126.com

【C/C++开发】C语言 DLL(动态链接库)中申请动态内存释放的问题的更多相关文章

  1. 在DLL动态链接库中封装VCL的MDI子窗体

    在DLL动态链接库中封装VCL的MDI子窗体不多说了,看代码就应该明白了,曾经我遇到的问题,现在放出来大家共享! 这里是工程文件的部分: 在DLL中封装MDI子窗体需要重写DLL入口函数,具体代码如下 ...

  2. VC 使用msxml6.dll动态链接库中的函数读写XML文件

    VC 使用msxml6.dll动态链接库中的函数读写XML文件 目录 1 引言 2 .dll使用方法 3 常用函数总结 4 实例应用 5 运行效果预览 6 补充说明 7 不足之处 8 更新   引言: ...

  3. 第10课 C++中的动态内存分配

    C++中的动态内存分配 C语言是通过库函数来完成动态内存分配的,而C++是通过关键字从语言层面支持的. C语言中的malloc是基于字节来进行内存申请的,C++中是基于类型来进行的. delete加上 ...

  4. 【C++】C++中的动态内存解析

    目录结构: contents structure [-] 动态内存和智能指针 使用shared_ptr管理内存 使用new直接管理内存 shared_ptr和new结合使用 unique_ptr we ...

  5. 因内存释放而引发的中断问题,dll中new的内存释放问题

    调试程序,每次关闭一个界面就会弹出中断错误. 为了确认这个问题,我将出现问题那一段代码中的函数一个个屏蔽,以此来确认到底哪个函数出现问题,缩小范围: 最后我发现,只要屏蔽掉checkIfFingerI ...

  6. 吴裕雄--天生自然C++语言学习笔记:C++ 动态内存

    栈:在函数内部声明的所有变量都将占用栈内存. 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存. 可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址.这种运 ...

  7. C# DumpBin使用 查看反射C++ dll 动态链接库中的函数

    DumpBin是Microsoft提供的一个用于查看.exe..dll文件信息的工具,其位于: C:\Program Files (x86)\Microsoft Visual Studio 10.0\ ...

  8. C语言的存储类别和动态内存分配

    存储类别分三大类: 静态存储类别 自动存储类别 动态分配内存 变量.对象--->内存管理 内存考虑效率(时间更短.空间更小) 作用域 链接.---->空间 存储器   ----->时 ...

  9. c++中的动态内存分配

    使用new和delete动态的分配和释放内存 使用new来分配新的内存块,通常情况下,如果成功,new将返回一个指针,指向分配的内存,否则将引发异常,使用new时,需要指定要为那种数据类型分配内存: ...

随机推荐

  1. LiteOS的内核——RTOS基本的特性

    在其他的rtos中,基本上也有类似的功能,ucos freertos,要是rtos的时候,务必选择自带的rtos功能,和裸机运行时有区别的

  2. P2709 小B的询问——普通莫队&&模板

    普通莫队概念 莫队:莫涛队长发明的算法,尊称莫队.其实就是优化的暴力. 普通莫队只兹磁询问不支持修改,是离线的. 莫队的基本思想:就是假定我得到了一个询问区间[l,r]的答案,那么我可以在极短(通常是 ...

  3. error MSB6006: “cmd.exe”已退出,代码为 3。

    error MSB6006: “cmd.exe”已退出,代码为 3. 这两天调程序遇到一个奇怪的问题. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4. ...

  4. MacOS使用zsh & oh-my-zsh

    shell 俗称壳,c 语言编写的命令解析器程序,是用户使用 linux 的桥梁. 目前常用的 Linux 系统和 OS X 系统的默认 Shell 都是 bash. zsh  和 bash 相似,且 ...

  5. 用javascript来判别回文数

    什么是回文数?通俗的说就是正着读和倒着读都一样的字符串(即使是数字也是可以看成字符串的). 所以下面回文数都是用字符串来表示的,即判断回文数就是对字符串的判断. 举几个回文数的例子: i love u ...

  6. pycharm同一目录下无法import其他文件

    如图:会出现带有红色波浪线,但是确实有random_walk文件 解决方法: 在当前文件下,右键找到mark  Directory as 然后选择source root,完工ok 再如图: 版权声明: ...

  7. Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)

    题目链接 http://codeforces.com/contest/576/problem/D 题解 把边按\(t_i\)从小到大排序后枚举\(i\), 求出按前\((i-1)\)条边走\(t_i\ ...

  8. nodejs的npm命令无反应的解决方案

    这二天用npm下载模块的时候输入npm命令完全无反应,不是加载的那种状态而是下标不停地在哪里闪...之后找解决方案,说要删除npmrc文件.强调:不是nodejs安装目录npm模块下的那个npmrc文 ...

  9. HA 模式 Hadoop+ZooKeeper+Hbase启动顺序

    一. 背景(原http://blog.csdn.net/u011414200/article/details/50437356 ,对其进行了一定更改) 1.1 网络上的大部分教程 都是机器间含有SSH ...

  10. Android学习_MVC与Adapter

    一.           MVC模式 MVC模式代表Model-View-Controller(模型-视图-控制器)模式.这种模式用于应用程序的分层开发. Model(模型):代表一个存取数据的对象或 ...