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

时间:2013-07-23 14:14:28

标签: c++ memory-management vector scope

CertificateInfo有一些CStrings and some 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(); }

CertificateInfo

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

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

5 个答案:

答案 0 :(得分:2)

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

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

  • 没有使用CollectCertificatesInfo的参数 - 这是故意的吗?
  • 正如其他人已经指出的那样,CertificateInfo的实例在这里被复制很多,并且它的复制结构可能会被破坏,但由于你没有给我们任何代码,所以不可能肯定地说那个班。

答案 1 :(得分:1)

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

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

稍后您尝试返回ca - 您按价值执行此操作。这通常很好,但只要知道编译器有点不会真正返回一个副本(请参阅here以获取更多详细信息),该副本将包含一个值(添加ca.push_back(ci)),该值是作为复制该函数中的本地版本。

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

这有帮助吗?

答案 2 :(得分:0)

肯定会有很多CertificateInfo的副本:

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

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

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

答案 3 :(得分:0)

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

我认为 CSWizardApp :: CheckCertificates()正文中的 store 变量应该是 CertificateStore ,或者你可能是暗示 PersonalStore CertificateStore 的子类?

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

答案 4 :(得分:0)

问题解决了。我使用指针CertificateArray中的CertificateStore::CollectCertificatesInfo变量,而不只是CertificateArray。这意味着内存分配在上,而不是堆栈上。因此,当执行离开CertificateStore::CollectCertificatesInfo时,用于该函数的堆栈上的内存被清除,但是堆上的CertificateInfo对象分配的内存未被释放,这是有道理的:) 。这是愚蠢的我之前没想过。

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