读书人

跨dll的内存分配?解决思路

发布时间: 2012-03-31 13:13:26 作者: rapoo

跨dll的内存分配?
我有一个第三方dll,没有源码
dll中提供的一些函数,函数内部会new一些内存以指针参数的形式返回给我(函数内部判断是否空指针,空的话new)
现在我在exe中delete这些内存就会崩溃。
如果我在exe中new好传进去,delete就没事。

现在怀疑是因为dll中,或者exe中重载了new和delete操作符,这种情况解决思路是什么?

我开始怀疑是debug和release的问题,我dll是release,把exe编译成release也不行

[解决办法]
DLL会管理自己的内存,不是重载new或者delete,在DLL里面new的对象必须由DLL负责delete。
[解决办法]
这就是运行库对应的问题。
谁分配谁释放是基本准则。
[解决办法]
如果确实需要这么做。
看看对方的 DLL 引用的是什么库来 new 这个操作。
你也引用同样的库来 delete 这个操作。
应该就没有问题。
总之,谁分配谁释放。
[解决办法]
如果第三方dll和自己的代码链接的不是同一套CRT的话,就可能会出问题。
第三方dll应该会确保把使用过的内存回收吧,不能确保回收的话就应该定义个处理回收内存的方法来用户。
没有的话,那就是设计问题了。
[解决办法]
C++中内存的分配与释放与C++运行库有直接的关系,我们知道C++运行库有六种:
DEBUG 单线程
DEBUG 多线程
DEBUG 多线程DLL
RELEASE 单线程
RELEASE 多线程
RELEASE 多线程DLL
分别有RELEASE和DEBUG模式下应用于单线程EXE/DLL,多线程EXE,多线程DLL.其中DEBUG模式RELEASE模式下分配内存有明显的区别,比如
char *p=new char[100];
应用程序分配了100个字节的内存,实际上在DEBUG模式下真正分配的是136个字节,多了36个字节,这36个字节是用于系统调试管理内存时使用,用来检查分配的内存是否有效,释放时是否被破坏,这36个字节分别在真正有内存(应用程序使用的内存)前后各32字节和4字节,头部(32字节)|应用程序使用的内存|尾部(4字节).


如果EXE和DLL分配内存的方式不一致,由DLL分配的内存,在EXE中释放就会出错,反过来也是一样。。。
[解决办法]

探讨
可是如果是一个函数,它的参数是一个数组(vector)的引用。
我调用的时候也不知道数组会有多大
我在外面定义一个数组,传入函数
之后数组肯定是在exe里析构吧?
那这样的情况怎么保证谁分配谁释放呢

[解决办法]
谁分配的内存谁来释放,因为两个地方new和delele使用的可能不是同一个库
[解决办法]
你自己有解决办法了。就是在你自己的exe里面new,自己delete。对于这种跨模块的内存分配和释放的问题最好的办法就是在同一个模块里面分配释放。否则 内存的分配和释放很大可能不对应同一段内存
[解决办法]
探讨

可是如果是一个函数,它的参数是一个数组(vector)的引用。
我调用的时候也不知道数组会有多大
我在外面定义一个数组,传入函数
之后数组肯定是在exe里析构吧?
那这样的情况怎么保证谁分配谁释放呢

[解决办法]
http://topic.csdn.net/u/20090325/14/688e70a5-e053-4ca6-a006-4c3dcbb48591.html你看完这个之后就不会有其他想法了。
[解决办法]
最好问dll的提供者有没有导出内存的释放函数呗
[解决办法]
那可能人家那个 DLL 的用法不是你想象的那样。
可能会有一个函数提示你,需要多大的内存。

[解决办法]
《windows核心编程》中的一段话
注意必须注意的是,单个地址空间是由一个可执行模块和若干个D L L模块组成的。这些模块中,有些可以链接到静态版本的C / C + +运行期库,有些可以链接到一个D L L版本的C / C + +运行期库,而有些模块(如果不是用C / C + +编写的话)则根本不需要C / C + +运行期库。许多开发人员经常会犯一个常见的错误,因为他们忘记了若干个C / C + +运行期库可以存在于单个地址空间中。请看下面的代码:


VOID EXEFunc()
{
PVOID pv = DLLFunc();
//Access the storage pointed to by pv...
//Assumes that pv is in EXE's C/C++ run-time heap
free(pv);
}

PVOID DLLFunc()
{
//Allocate block from DLL's C/C++ run-time heap
return(malloc(100));
}
那么你是怎么看待这个问题的呢?上面这个代码能够正确运行吗? D L L函数分配的内存块是由E X E的函数释放的吗?答案是可能的。上面显示的代码并没有为你提供足够的信息。如果E X E和D L L都链接到D L L的C / C + +运行期库,那么上面的代码将能够很好地运行。但是,如果两个模块中的一个或者两个都链接到静态C / C + +运行期库,那么对free函数的调用就会失败。我经常看到编程人员编写这样的代码,结果都失败了。
[解决办法]
DLL里的内存申请,由DLL来释放,EXE里的申请,由EXE释放。。




[解决办法]
内存应用一般都是谁申请谁释放的。

非自己申请的内存,释放时会引起申请模块或者其他模块应用时出现地址访问异常的。
[解决办法]
那是当然,他内部new的,当你卸载库或超出作用域的时候内部肯定会做delete操作。
你外部delete,他再delete当然有问题了。

读书人网 >C++

热点推荐