Почему этот явный деструктор вызывает повреждение памяти в общем 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 буфер.

Другие вопросы по тегам