我试图弄清楚当我离开方法时如何修复我的访问冲突。我从使用独特的ptr变为共享ptr,所以也许它是shared_ptrs的一个微妙之处。我无法在线查找有关shared_ptrs的信息。我以前也有下面注释掉的行,不得不改变它以使用我的新类而不是使用唯一ptrs对象的向量。当我取消注释大括号时,它没有访问冲突。
方法如下:
int ExecuteIt(String& sFileName, String& sInput, String& sOutput)
{
// make sure we have valid data
if (sFileName.isEmpty() || sInput.isEmpty() || sOutput.isEmpty())
{
return -1;
}
int iResult = -1; // error
CreateDocW(sOutput, sFileName, pWriter, pDeleteWriter);
CreateDocR(sInput, sFileName, pReader, pDeleteReader);
//{
shared_ptr<IFJ> m_spIFJTemp = pReader->vMethodImpl1();
if (m_spIFJTemp && !m_spIFJTemp->isVectorIfdEmpty())
{
//auto RootContainerIter = vDocRootContainers->begin();
pWriter->vMethodImpl2(m_spIFJTemp);
//pWriter->vMethodImpl2(move(*RootContainerIter));
iResult = 0; // Success
}
//}
Cleanup(); //before step into cleanup m_spIFJTemp has shared_ptr {m_spVectorIFD={ size=1 } } [2 strong refs] [make_shared] std::shared_ptr<IFJ>
//after cleanup m_spIFJTemp has shared_ptr {m_spVectorIFD={ size=??? } } [1 strong ref] [{_Uses=1 _Weaks=1 }] std::shared_ptr<IFJ>
return iResult; //when I uncomment the extra curly brackets it steps
//into a memory _Decref() and has access violation
//reading location in _Destroy()
}
清理是这样的:
void Cleanup()
{
// Cleanup the reader
if (pDeleteReader != nullptr)
{
pDeleteReader();
pDeleteReader = nullptr;
}
// unload the reader
if (pReaderLibHandle != nullptr)
{
dlclose(pReaderLibHandle);
pReaderLibHandle = nullptr;
}
// Cleanup the writer
if (pDeleteWriter != nullptr)
{
pDeleteWriter();
pDeleteWriter = nullptr;
}
// unload the writer
if (pWriterLibHandle != nullptr)
{
dlclose(pWriterLibHandle);
pWriterLibHandle = nullptr;
}
}
我在网上找到了这个信息accessviolation,但我查了一下,我没有用new创建任何shared_ptr,我一直试图在调试器中查看它而我没有确定shared_ptr的强大参考。
如果您对可能导致此问题的原因有任何意见,请与我们联系。我将不胜感激任何有用的回应。
答案 0 :(得分:1)
我不知道哪个班级pReader
指的是,但我怀疑以下内容:
您将pReader->vMethodImpl1()
的结果放入共享指针中。这意味着当您离开方法时,此共享指针将在该指针上调用delete
。
但是,我怀疑vMethodImpl1()
不会放弃所返回对象的“所有权”并在pReader
内保留引用,当您致电Cleanup
然后pReader
时被销毁并且自己在存储在共享指针中的指针上调用delete
。因此,您尝试两次破坏该对象。
我建议你只使用
IFJ* m_spIFJTemp = ...
而不是
shared_ptr<IFJ> m_spIFJTemp = ...
然后使用valgrind
或其他工具检查内存是否实际被释放。
答案 1 :(得分:0)
这样可以清理这些内容,因此当shared_ptr离开范围时没有问题:
m_spIFJTemp.reset(); /* remove shared_ptr referece before calling destructors */
Cleanup();
另一件可行的方法是在离开ExecuteIt方法后调用Cleanup。