1

这段代码有什么问题,我该如何解决?

#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() 线修复这种行为,但我认为有一个更正确的解决方案......

4

1 回答 1

6

因为你所做的没有任何意义。您正在创建一个对象,然后... 在同一地址上创建一个对象。

然后你正在摧毁那个地址上的对象......然后你又在摧毁它。

那应该如何工作?

你要求一个CSlot对象向量,这就是你得到的。您要求它的大小为 1,因此它包含一个CSlot对象,完全构建并准备好执行操作。CSlot所以在它之上构造一个对象是没有意义 的。

如果要使用placement new 并直接调用析构函数,则应将其放入空char缓冲区中。

于 2011-12-29T10:12:31.797 回答