如何避免在c++非clr到clr dll之间引发异常时发生内存泄漏
how to avoid memory leak when throwing exception between a c++ non clr to clr dlls?
在我的解决方案中,我有一些c++项目(dll),它们在使用c#(.NET)dll时启用了clr。
当在非clr项目(dll)与启用clr的项目之间抛出异常并通过引用捕获它时,我检测到内存泄漏。当我省略了在c#dll中的使用,并将项目更改为非clr时,泄漏就消失了。
或者,如果我抛出新异常并在catch语句中删除它,那么泄漏就消失了。Exception类是从std::Exception继承而来的,带有更多用于一般描述、函数名等的字符串。
森博迪能解释泄漏吗?或者我该如何避免泄漏?
使用不同编译器/编译器设置编译的不同dll在对象布局方面通常不兼容&内存分配&取消分配。这就是为什么您应该避免在一个dll中分配对象,而在另一个dll中将其取消分配。正如您所注意到的,这可能会导致内存泄漏。
如果您想跨模块边界传递错误信息,请通过错误代码或处理错误信息的机制(例如SEH异常或COM异常)
好的,这里有一些澄清:
- 一个对象由两部分组成——数据和代码。对象实例是需要调用代码的数据和知识。对于非虚拟函数,该知识在编译时解析,对于虚拟函数,它在运行时通过数据中的指针(this)解析
- 分配:数据必须分配到某个地方。有两种可能性——堆栈和堆。堆栈通常用于小数据。它有一些好处,比如在保留作用域时自动取消对对象的分配。堆栈还存储返回地址等。每当调用"new"来分配对象时,都会在堆上进行分配。堆栈的正常空间是1或2M字节,而现代计算机的堆大小在多GB的范围内。因此,每个较大的应用程序都会将堆用于其大部分数据结构。有时它隐藏在对象后面,例如std::vector。向量中的数据存储在堆上,而管理该缓冲区的对象可以在堆栈上
- 对象布局&堆内存管理:不同编译器实现之间对象的大小可能不同;设置。一个例子是visualstudio中容器的大小。某些编译器实现了仅在调试中可用的附加帮助器成员,并且如果代码是在调试中编译的,则会增加大小。此外,存储器分配&解除分配例程在debug&释放以检测内存分配&去分配错误,未初始化的变量等等。这两个事实导致了一个简单的结论:永远不要在与分配内存的模块不同的模块中去分配(例外:如果你可以控制编译设置)。这也排除了例外情况
相关文章:
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 从CLR GUI实现非托管班级时,stackoverflow异常提出
- 如何避免在c++非clr到clr dll之间引发异常时发生内存泄漏
- 调用我的CLR项目时,KernelBase.dll出现未处理的异常
- 从混合模式c++项目中的CLR-to-SEH异常中获取明智的信息
- CLR在非CLR创建的线程中承载异常处理
- CLR 有胖或小的异常框架