离开方法时访问冲突

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。