Почему этот явный деструктор вызывает повреждение памяти в общем ptr?
Что не так с этим кодом и как я могу это исправить?
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <vector>
struct CTest
{
CTest()
{ std::cout << "ctor CTest" <<std::endl; }
~CTest()
{ std::cout << "dtor CTest" <<std::endl; }
};
struct CSlot
{
CSlot() : m_test(new CTest()), m_num(123)
{ }
~CSlot()
{
// m_test.reset(); // this line fixed the code but I don't know why
m_num = -1;
}
boost::shared_ptr<CTest> m_test;
int m_num;
};
int main()
{
std::vector<CSlot> testVector(1);
std::cout << "1" << std::endl;
new (&testVector[0]) CSlot();
// clear slot
testVector[0].~CSlot();
std::cout << "2" << std::endl;
}
этот код выглядит как работающий и печатает:
ctor CTest
1
ctor CTest
dtor CTest
2
но иногда сбой программы и valgrind всегда говорят:
==13372== Invalid read of size 4
==13372== at 0x400D8F: boost::detail::atomic_exchange_and_add(int*, int)
...
Я могу исправить это поведение с помощью строки m_test.reset(), но я думаю, что есть более правильное решение...
1 ответ
Потому что то, что ты делаешь, не имеет смысла. Вы создаете объект, а затем... создаете объект по тому же адресу.
Затем вы уничтожаете объект по этому адресу... И затем вы уничтожаете его снова.
Как это должно работать?
Вы попросили вектор CSlot
объекты, так что это то, что вы получили. Вы просили, чтобы он имел размер 1, поэтому он содержит один CSlot
объект, полностью построен и готов к действию. Так что не имеет смысла строить CSlot
объект поверх него.
Если вы хотите использовать размещение новых и вызвать деструктор напрямую, вы должны сделать это в пустом char
буфер.