如何避免在C++中自动解除分配

How can I avoid automatic deallocate in C++?

本文关键字:解除分配 C++ 何避免      更新时间:2023-10-16

一个CertificateInfo有一些CStrings and some C时间`。

当执行达到CheckCertificates的右大括号时,会因为堆损坏而中断执行。最后一个调用堆栈帧是CCD_ 3从解除分配CCD_。

    typedef vector<CertificateInfo> CertificateArray;
    CertificateArray CertificateStore::CollectCertificatesInfo(CertificateArray &ca, 
                                                               bool bExpirationDateOnly /* = false */,
                                                               bool bCertSignOnly /* = true */)
    {
        CertificateArray aCertificates;
         while(Precondition())
         {
             CertificateInfo ci;
             if(Condition(ci))
             {
                 aCertificates.push_back(ci);
             }
         }
         return aCertificates;
    }
    void CSWizardApp::CheckCertificates(bool bOnDemand)
    {
        PersonalStore store;
        CertificateArray aCertificates;
        aCertificates = store.CollectCertificatesInfo();
    }

我做错了什么?我该如何解决?

我注意到,对于CertificateArray中返回的1个CertificateInfo,构造函数将被调用一次,而CertificateInfo字段的析构函数将被调用3次。

您正在定义一个局部变量ca,它隐藏了您传入的参数ca。虽然这不是唯一的问题,但上面的代码几乎肯定不会达到您期望的效果。

编辑:因为您现在已经从参数中消除了局部变量的歧义:

  • 没有使用CollectCertificatesInfo的任何参数——这是故意的吗
  • 正如其他人已经指出的那样,CertificateInfo的实例在这里被大量复制,它的复制结构可能会被破坏,但这是不可能确定的,因为你没有给我们任何该类的代码

好吧,有几件事你需要小心。

您将ca声明为函数的参数,也将其声明为本地变量。这意味着,当您调用ca.push_back(ci)时,实际上是在尝试插入本地版本。

稍后,您将尝试返回ca,这是按值执行的。这通常很好,但请注意,编译器不会真正返回一个副本(有关更多详细信息,请参阅此处),该副本将包含一个值(添加了ca.push_back(ci)),该值是作为该函数中本地版本的副本创建的。

如果对CertificateInfo不了解一点,很难说得更多。它是否包含在析构函数中清除的指针pUserData?如果是这样,当您执行复制时,如果您没有一些逻辑来复制该变量指向的堆数据,那么当函数返回并且ci的本地版本被销毁时(如果析构函数就是这样写的,那么也会获取与pUserData相关联的数据),则返回的副本中的指针将无效。

这有帮助吗?

肯定有很多CertificateInfo的副本在进行:

CertificateInfo ci; // 1st constructor
push_back(ci);      // 1st copy
return ca;          // 2nd copy

Condition(ci)可能是另一个副本——Condition是如何声明的?

确保CertificateInfo的副本ctr正确无误。

您发布的代码有些过于简单:传递给CollectCertificatesInfo()的参数都没有使用,唯一的参数可能是ca,但您在函数定义中重新声明了它,从而阻止了对传递值的任何访问。

我假设CSWizardApp::CheckCertificates()主体中的store变量应该是CertificateStore,或者您可能在暗示PersonalStoreertificateStore的子类?

我建议你在寻求进一步帮助之前先清理一下代码或完成它,因为很难弄清楚你要做什么。

问题已解决。我使用了指向CertificateStore::CollectCertificatesInfoCertificateArray变量的指针,而不是仅指向CertificateArray。这意味着内存分配在上,而不是堆栈上。因此,当执行退出CertificateStore::CollectCertificatesInfo时,堆栈上用于函数的内存将被清除,但为堆上的CertificateInfo对象分配的内存不会被释放,这是有道理的:)。我早些时候没有考虑这件事,真傻。

谢谢你们的帮助,伙计们:)