C++ 如何避免在C++;?

C++ 如何避免在C++;?,c++,memory-management,vector,scope,C++,Memory Management,Vector,Scope,CertificateInfo有一些cstring和一些CTimes` 当执行到达CheckCertificates的右括号时,由于堆损坏,它会中断执行。最后一个调用堆栈帧是 CSWizard.exe_CrtIsValidHeapPointer(const void*pUserData=0x00ba8e08)来自解除分配aCertificates typedef vector<CertificateInfo> CertificateArray; Certificat

CertificateInfo
有一些
cstring和一些
CTimes`

当执行到达CheckCertificates的右括号时,由于堆损坏,它会中断执行。最后一个调用堆栈帧是
CSWizard.exe_CrtIsValidHeapPointer(const void*pUserData=0x00ba8e08)
来自解除分配
aCertificates

    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();
    }
typedef向量证书array;
CertificateArray CertificateStore::CollectCertificatesInfo(CertificateArray&ca,
bool bExpirationDateOnly/*=false*/,,
bool bCertSignOnly/*=true*/)
{
证书可以是尖刻的;
while(前提条件())
{
认证信息ci;
如果(条件(ci))
{
尖刻。推回(ci);
}
}
还尖刻;
}
void CSWizardApp::CheckCertificates(bool-bOnDemand)
{
个人商店;
证书可以是尖刻的;
aCertificates=store.CollectCertificatesInfo();
}
我做错了什么?我该如何修复它


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

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

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

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

    • 肯定有很多
      认证信息的副本正在进行:

      CertificateInfo ci; // 1st constructor
      push_back(ci);      // 1st copy
      return ca;          // 2nd copy
      
      条件(ci)
      可能是另一个副本-如何声明
      条件


      确保CertificateInfo的副本ctr正确。

      好的,有几件事需要注意

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

      稍后,您将尝试返回
      ca
      ——这是通过值来实现的。这通常很好,但请注意,编译器实际上不会返回一个副本(有关更多详细信息,请参阅),该副本将包含一个值(添加了
      ca.push_back(ci)
      ),该值是在该函数中创建的本地版本的副本

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


      这有帮助吗?

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

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

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

      问题已解决。我在
      CertificateStore::CollectCertificatesInfo
      中使用了指向
      CertificateArray
      变量的指针,而不仅仅是
      CertificateArray
      。这意味着内存分配在堆上,而不是堆栈上。因此,当执行从
      CertificateStore::CollectCertificatesInfo
      中退出时,用于函数的堆栈内存被清除,但为堆上的
      CertificateSInfo
      对象分配的内存没有被释放,这很有意义:)。真傻,我没早点想到


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

      复制构造函数也参与其中。在
      CertificateArray
      类中正确定义它们。这听起来像是您试图“猜测”问题是什么,并试图找到您猜测的解决方案,与其实际解决根本问题(即您的设计中出现了一些问题),尤其是在复制您的内容方面。不如禁用自动解除分配,也就是raii,您应该调试崩溃的真正原因…@Matsbeterson我不想猜测,我将尝试定义复制构造函数,看看它是否可以这样工作,谢谢,@avakarMy bad,局部变量在实际代码中的名称不同。我现在更改了它。因此,
      CollectCertificatesInfo
      的所有参数都未使用?嗯,没有。我尝试了在
      CollectCertificatesInfo
      中创建
      CertificateARay
      ,并将
      aCertificates
      作为参数传递,然后直接将其推回,这就是我将其作为参数的原因,但我在评估条件时使用布尔值。CertificateInfo没有