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
中返回的1CertificateInfo
,构造函数将被调用一次,而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没有