如何避免在c++;非clr到clr DLL? 在我的解决方案中,我有一些C++项目(DLL),它们使用的是CL~(.net)DLL。

如何避免在c++;非clr到clr DLL? 在我的解决方案中,我有一些C++项目(DLL),它们使用的是CL~(.net)DLL。,c++,memory-management,interop,clr,C++,Memory Management,Interop,Clr,当在非clr项目(dll)与启用clr的项目之间引发异常并通过引用捕获它时,我检测到内存泄漏。当我省略了c#dll中的用法,并将项目更改为非clr时,泄漏就消失了 或者,如果我抛出新异常并在catch语句中删除它,那么泄漏就消失了。 Exception类是从std::Exception继承而来的,带有更多的字符串用于一般描述、函数名等 sombody能否解释泄漏,或者我如何避免泄漏 使用不同编译器/编译器设置编译的不同DLL在对象布局、内存分配和取消分配方面通常不兼容。这就是为什么您应该避免在一

当在非clr项目(dll)与启用clr的项目之间引发异常并通过引用捕获它时,我检测到内存泄漏。当我省略了c#dll中的用法,并将项目更改为非clr时,泄漏就消失了

或者,如果我抛出新异常并在catch语句中删除它,那么泄漏就消失了。 Exception类是从std::Exception继承而来的,带有更多的字符串用于一般描述、函数名等


sombody能否解释泄漏,或者我如何避免泄漏

使用不同编译器/编译器设置编译的不同DLL在对象布局、内存分配和取消分配方面通常不兼容。这就是为什么您应该避免在一个dll中分配对象,而在另一个dll中取消分配对象。正如您所注意到的,这可能会导致内存泄漏

如果您希望跨模块边界传递错误信息,请通过错误代码或处理错误信息的机制(例如SEH异常或COM异常)传递错误信息


好的,这里有一些澄清:

  • 一个对象由两部分组成——数据和代码。对象实例是需要在调用代码时调用的数据和知识。对于非虚函数,此知识在编译时解析;对于虚函数,此知识在运行时通过数据中的指针(this)解析
  • 分配:数据必须分配到某个地方。有两种可能——堆栈和堆。堆栈通常用于小数据。它有一些好处,比如在离开作用域时自动取消对象的分配。堆栈还存储返回地址等。每当调用“new”来分配对象时,都会在堆上分配该对象。堆栈的正常空间为1或2Mbyte,而对于现代计算机,堆大小在多GB的范围内。由于这个原因,每个较大的应用程序在其大多数数据结构中都使用堆。有时这会隐藏在对象后面——例如std::vector。向量中的数据存储在堆上,而管理此缓冲区的对象可以在堆栈上
  • 对象布局和堆内存管理:不同的编译器实现和设置之间,对象的大小可能不同。一个例子是VisualStudio中容器的大小。某些编译器实现附加的帮助器成员,这些成员仅在调试中可用,如果代码是在调试中编译的,则会增加其大小。此外,内存分配和释放例程在调试和释放中可以不同,以检测内存分配和取消分配错误、未初始化变量等。这两个事实得出了一个简单的结论:决不要在分配内存的模块之外的模块中取消分配(例外:如果可以控制编译设置)。这也排除了例外情况

  • 使用不同编译器/编译器设置编译的不同DLL在对象布局、内存分配和取消分配方面通常不兼容。这就是为什么您应该避免在一个dll中分配对象,而在另一个dll中取消分配对象。正如您所注意到的,这可能会导致内存泄漏

    如果您希望跨模块边界传递错误信息,请通过错误代码或处理错误信息的机制(例如SEH异常或COM异常)传递错误信息


    好的,这里有一些澄清:

  • 一个对象由两部分组成——数据和代码。对象实例是需要在调用代码时调用的数据和知识。对于非虚函数,此知识在编译时解析;对于虚函数,此知识在运行时通过数据中的指针(this)解析
  • 分配:数据必须分配到某个地方。有两种可能——堆栈和堆。堆栈通常用于小数据。它有一些好处,比如在离开作用域时自动取消对象的分配。堆栈还存储返回地址等。每当调用“new”来分配对象时,都会在堆上分配该对象。堆栈的正常空间为1或2Mbyte,而对于现代计算机,堆大小在多GB的范围内。由于这个原因,每个较大的应用程序在其大多数数据结构中都使用堆。有时这会隐藏在对象后面——例如std::vector。向量中的数据存储在堆上,而管理此缓冲区的对象可以在堆栈上
  • 对象布局和堆内存管理:不同的编译器实现和设置之间,对象的大小可能不同。一个例子是VisualStudio中容器的大小。某些编译器实现附加的帮助器成员,这些成员仅在调试中可用,如果代码是在调试中编译的,则会增加其大小。此外,内存分配和释放例程在调试和释放中可以不同,以检测内存分配和取消分配错误、未初始化变量等。这两个事实得出了一个简单的结论:决不要在分配内存的模块之外的模块中取消分配(例外:如果可以控制编译设置)。这也排除了例外情况

  • 嗯,当你“抛出新的T”时,你需要新的东西,所以必须有人删除它。仅仅抛出一个没有新的实例有什么不对?漏洞是当我试图抛出一个实例(没有新的)并通过引用捕获它时请正确标记您的问题;难道不应该有一个
    clr
    net
    标签或什么的吗?谢谢,我在这里的第一个问题……好吧,当你“抛出新t”时,你会有新的东西,所以必须有人删除它。只是开个insta有什么不对