1

ACertificateInfo有一些CStrings and someCTimes`。

当执行到达 CheckCertificates 的右括号时,由于堆损坏,它会中断执行。最后一个调用堆栈帧 CSWizard.exe!_CrtIsValidHeapPointer(const void * pUserData=0x00ba8e08)来自 deallocating 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();
    }

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

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

4

5 回答 5

2

ca您正在定义一个隐藏您传入的参数的局部变量ca。虽然这不是这里唯一的问题,但上面的代码几乎肯定不会像您期望的那样做。

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

  • 没有使用任何参数CollectCertificatesInfo- 这是故意的吗?
  • 正如其他人已经指出的那样,CertificateInfo这里的实例被复制了很多,并且它的复制结构可能会被破坏,但由于您没有为该类提供任何代码,因此无法肯定地说。
于 2013-07-23T14:19:53.340 回答
1

好的,有几件事你需要注意。

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

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

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

这有帮助吗?

于 2013-07-23T14:36:01.857 回答
0

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

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

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

确保 CertificateInfo 的副本 ctr 正确。

于 2013-07-23T14:22:48.133 回答
0

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

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

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

于 2013-07-23T14:48:48.433 回答
0

问题解决了。我使用了一个指向变量CertificateArrayinCertificateStore::CollectCertificatesInfo而不是CertificateArray. 这意味着内存是在堆上分配的,而不是在栈上。因此,当执行结束时CertificateStore::CollectCertificatesInfo,用于函数的堆栈上的内存被清除,但为CertificateInfo堆上的对象分配的内存不会被释放,这是有道理的:)。很傻,我之前没有考虑过。

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

于 2013-07-25T12:58:19.070 回答