离开方法时访问冲突
Access violation when leave method
我正在尝试弄清楚在离开方法时如何解决我的访问冲突。我从使用唯一 ptr 更改为共享 ptr,所以这可能是 shared_ptrs 的一个微妙之处。我无法在线查找 shared_ptrs 上的信息。我也曾经在下面注释掉一行,不得不将其更改为使用我的新 class 而不是使用唯一 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,但我检查了一下,我没有用新的 shared_ptr 创建任何信息,我一直试图在调试器中查看它,但我没有确定 shared_ptr 的强引用。
如果您对可能导致此问题的原因有任何意见,请告诉我。如果有任何有用的回复,我将不胜感激。
我不知道 class pReader
指的是哪个,但我怀疑如下:
您将 pReader->vMethodImpl1()
的结果放入共享指针。这意味着当您离开该方法时,此共享指针将对该指针调用 delete
。
但是我怀疑 vMethodImpl1()
不会放弃返回的对象的 "ownership" 并在 pReader
中保留一个引用,当您调用 Cleanup
然后 pReader
被破坏并且它自己在您存储在共享指针中的指针上调用 delete
。因此,您尝试两次破坏该对象。
我建议你只使用
IFJ* m_spIFJTemp = ...
而不是
shared_ptr<IFJ> m_spIFJTemp = ...
然后使用valgrind
或其他工具来检查内存是否真的被释放了。
这清理了一切,因此 shared_ptr 在离开范围时没有问题:
m_spIFJTemp.reset(); /* remove shared_ptr referece before calling destructors */
Cleanup();
另一件可行的事情是在离开 ExecuteIt 方法后调用 Cleanup。
我正在尝试弄清楚在离开方法时如何解决我的访问冲突。我从使用唯一 ptr 更改为共享 ptr,所以这可能是 shared_ptrs 的一个微妙之处。我无法在线查找 shared_ptrs 上的信息。我也曾经在下面注释掉一行,不得不将其更改为使用我的新 class 而不是使用唯一 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,但我检查了一下,我没有用新的 shared_ptr 创建任何信息,我一直试图在调试器中查看它,但我没有确定 shared_ptr 的强引用。
如果您对可能导致此问题的原因有任何意见,请告诉我。如果有任何有用的回复,我将不胜感激。
我不知道 class pReader
指的是哪个,但我怀疑如下:
您将 pReader->vMethodImpl1()
的结果放入共享指针。这意味着当您离开该方法时,此共享指针将对该指针调用 delete
。
但是我怀疑 vMethodImpl1()
不会放弃返回的对象的 "ownership" 并在 pReader
中保留一个引用,当您调用 Cleanup
然后 pReader
被破坏并且它自己在您存储在共享指针中的指针上调用 delete
。因此,您尝试两次破坏该对象。
我建议你只使用
IFJ* m_spIFJTemp = ...
而不是
shared_ptr<IFJ> m_spIFJTemp = ...
然后使用valgrind
或其他工具来检查内存是否真的被释放了。
这清理了一切,因此 shared_ptr 在离开范围时没有问题:
m_spIFJTemp.reset(); /* remove shared_ptr referece before calling destructors */
Cleanup();
另一件可行的事情是在离开 ExecuteIt 方法后调用 Cleanup。