I implement a new module using shared_ptr etc. in our legacy app, however I get a access violation, when shared_ptr is calling the destructor.
app:
case ENUM_DATA:
{
std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg)); // _stringmsg is initialized before
Process(msg);
break;
}
Process():
bool Process(std::tr1::shared_ptr<CDataMsg> msg)
{
try
{
switch (msg->getDataType())
{
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;
}
default:;
}
return true;
}
catch (...)
{
// exception handling
}
return false;
}
Destructor:
CDataMsg::~CDataMsg()
{
if (m_data)
delete m_data;
m_data = NULL;
}
m_data is a CMyData* (cannot be changed at this point).
CDataMsg is a container, which holds data of type CMyData. CmyDataChild is a subclass of CMyData, which is used here.
I have breakpoint in the destructor, but the debugger stops only, when shared_ptr is calling it and then I get the access violation already.
As you have confirmed in your comment msg->getData()
returns a pointer to a member variable of msg
(presumably m_data
) and it will be deleted when this switch
block scope exits:
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;
}
The destructor of msg
will be invoked later when this switch
block scope exits:
case ENUM_DATA:
{
std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg));
Process(msg);
break;
}
and attempt to redelete
the member variable m_data
.
Also:
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild>
data(std::tr1::static_pointer_cast<CMyDataChild>(base));
...
}
data
is pointing to the same object as base
. When this scope exits base
will be deleted
ed twice.