Visual c++ 在旧代码上使用共享ptr时发生访问冲突

Visual c++ 在旧代码上使用共享ptr时发生访问冲突,visual-c++,shared-ptr,access-violation,Visual C++,Shared Ptr,Access Violation,我使用shared_ptr等实现了一个新模块。在我们的遗留应用程序中,当shared_ptr调用析构函数时,我遇到了访问冲突 应用程序: m_数据是CMyData*(此时无法更改) CDATA MSG是一个容器,它保存CMyData类型的数据。CmyDataChild是CMyData的一个子类,这里使用它 我在析构函数中有断点,但调试器只有在shared_ptr调用它时才会停止,然后我就已经得到了访问冲突。每当我看到这样的错误时,我都会立即想到double delete std::tr1::sh

我使用shared_ptr等实现了一个新模块。在我们的遗留应用程序中,当shared_ptr调用析构函数时,我遇到了访问冲突

应用程序:

m_数据是CMyData*(此时无法更改)

CDATA MSG是一个容器,它保存CMyData类型的数据。CmyDataChild是CMyData的一个子类,这里使用它


我在析构函数中有断点,但调试器只有在shared_ptr调用它时才会停止,然后我就已经得到了访问冲突。

每当我看到这样的错误时,我都会立即想到double delete

std::tr1::shared_ptr<CMyData> base(msg->getData());
if (m_data) delete m_data;  //- in CDataMsg destructor
std::tr1::shared_ptr base(msg->getData());
如果(m_数据)删除m_数据;//-在CDataMsg析构函数中

“m_数据”是否有可能被删除两次?一次在共享ptr中,一次在CDataMsg析构函数中。

每当我看到这样的bug时,我立刻想到double delete

std::tr1::shared_ptr<CMyData> base(msg->getData());
if (m_data) delete m_data;  //- in CDataMsg destructor
std::tr1::shared_ptr base(msg->getData());
如果(m_数据)删除m_数据;//-在CDataMsg析构函数中

“m_数据”是否有可能被删除两次?一次在共享ptr中,一次在CDATA msg析构函数中。

正如您在注释
msg->getData()
中确认的那样,返回一个指向
msg
的成员变量的指针(可能是
m\u data
),当此
开关
块作用域退出时,它将被删除:

case ENUM_MYDATATYPE:
{
    std::tr1::shared_ptr<CMyData> base(msg->getData());
    std::tr1::shared_ptr<CMyDataChild>
        data(std::tr1::static_pointer_cast<CMyDataChild>(base));

    // do some stuff with data
    std::tr1::shared_ptr<CRequest>
        request(new CRequest(data->getParam1(), data->getParam2()));
    handler->AddRequest(request->getBin());
    break;
}
case ENUM_DATA:
{
    std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg));
    Process(msg);
    break;
}
并尝试重新
删除成员变量
m_data

此外:

case ENUM\u MYDATATYPE:
{
std::tr1::shared_ptr base(msg->getData());
std::tr1::共享\u ptr
数据(std::tr1::静态_指针_转换(基));
...
}

data
指向与
base
相同的对象。当此作用域退出时,
base
将被
删除
两次。

正如您在注释
msg->getData()
中确认的那样,返回一个指向
msg
的成员变量的指针(可能是
m_data
),并且当此
开关
块作用域退出时,它将被删除:

case ENUM_MYDATATYPE:
{
    std::tr1::shared_ptr<CMyData> base(msg->getData());
    std::tr1::shared_ptr<CMyDataChild>
        data(std::tr1::static_pointer_cast<CMyDataChild>(base));

    // do some stuff with data
    std::tr1::shared_ptr<CRequest>
        request(new CRequest(data->getParam1(), data->getParam2()));
    handler->AddRequest(request->getBin());
    break;
}
case ENUM_DATA:
{
    std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg));
    Process(msg);
    break;
}
并尝试重新
删除成员变量
m_data

此外:

case ENUM\u MYDATATYPE:
{
std::tr1::shared_ptr base(msg->getData());
std::tr1::共享\u ptr
数据(std::tr1::静态_指针_转换(基));
...
}

data
指向与
base
相同的对象。当此作用域退出时,
base
将被
删除
两次。

是否分配并返回一个新的
CMyData
对象,或者是否返回一个指向
msg
成员的
CMyData
的指针?是否在处理堆损坏时返回指向msgwhen的CMyData成员的指针,标准C++类是查找原因的最后一个地方。使用
中的调试分配器。是否
msg->getData()
分配并返回一个新的
CMyData
对象,或者是否返回一个指向
msg
成员的
CMyData
的指针?是否在处理堆损坏时返回指向msgwhen的CMyData成员的指针,标准C++类是查找原因的最后一个地方。使用
中的调试分配器。是的,您是对的。根据您的上述评论,我查看了
getData()
返回的
CMyData*
。但是,我可以使用
shared\u ptr
作为返回类型来修复它。谢谢你的帮助!是的,你说得对。根据您的上述评论,我查看了
getData()
返回的
CMyData*
。但是,我可以使用
shared\u ptr
作为返回类型来修复它。谢谢你的帮助!
case ENUM_MYDATATYPE:
{
    std::tr1::shared_ptr<CMyData> base(msg->getData());
    std::tr1::shared_ptr<CMyDataChild>
        data(std::tr1::static_pointer_cast<CMyDataChild>(base));
    ...
}