参考:首先,声明一点,凡是使用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. 6、DockerFile解析:三步走、保留字指令

    1.dockerfiel是什么 1.是什么 Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本. 2.构建三步骤 编写Dockerfile文件 docker bu ...

  2. [Spring] Spring Data JPA

    Previouly we need to define a DAO interface and a DAO impl for 'Employee', it is not so reuseable, s ...

  3. HDU 6049 - Sdjpx Is Happy | 2017 Multi-University Training Contest 2

    思路来源于 FXXL - - 一个比较奇怪的地方就是第三步可以不做,也就是ans至少为1,听说场内有提问的,然后 admin 说可以不做- - (wa的我心烦) /* HDU 6049 - Sdjpx ...

  4. 菜鸟刷面试题(五、Java容器篇)

    目录: java 容器都有哪些? Collection 和 Collections 有什么区别? List.Set.Map 之间的区别是什么? HashMap 和 Hashtable 有什么区别? 如 ...

  5. [Python自学] day-18 (1) (JS正则、第三方组件)

    一.JS的正则表达式 JS正则提供了两个方法: test():用于判断字符串是否符合规定: exec():获取匹配的数据: 1.test() 定义一个正则表达式: reg = /\d+/; // 用于 ...

  6. CSS测试题Ⅱ

    1.如何使用 CSS3 强制换行? A. word-wrap: break-word; B. text-wrap: break-word; C. text-wrap: force; D. text-w ...

  7. shell拷贝文件到另一台机器

    #!/bin/bash data=$(date "+%Y-%m-%d %H:%M:%S") ip='192.168.10.14' password='fan' gitBak='/v ...

  8. codeforces#1183H. Subsequences(字符串dp)

    题目链接: http://codeforces.com/contest/1183/problem/H 题意: 给出一个长度为$n$的字符串,得到$k$个子串,子串$s$的花费是$n-|s|$ 计算最小 ...

  9. iOS UILabel显示HTML文本

    NSString * htmlString = @"<html><body> Some html string \n <font size=\"13\ ...

  10. 如何选CDN:互联网大直播时代的CDN选择指南

    转: 如何选CDN:互联网大直播时代的CDN选择指南 from:  http://www.chnvideo.com/blog-classic-cdn.html SRS 编码器   如何选CDN:互联网 ...