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

参考:首先,声明一点,凡是使用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,' ',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 ",employeeName );       /* 这里会输出 susan */

                    freeTestFuncMemory((&employeeName);

                    printf("%s ",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