C++ &引用;地址不来自malloc();使用电子围栏时出错

C++ &引用;地址不来自malloc();使用电子围栏时出错,c++,shared-ptr,electric-fence,C++,Shared Ptr,Electric Fence,我一直在写一个测试用例程序来演示我的一个更大的程序的问题, 而且测试用例有一个原始程序没有的bug 下面是头文件: // compiled with g++ -I/usr/local/bin/boost_1_43_0 -Wall -std=c++0x -g test.cpp #include <bitset> #include <boost/shared_ptr.hpp> #include <vector> typedef std::vector<

我一直在写一个测试用例程序来演示我的一个更大的程序的问题, 而且测试用例有一个原始程序没有的bug

下面是头文件:

// compiled with g++ -I/usr/local/bin/boost_1_43_0 -Wall -std=c++0x -g test.cpp

#include <bitset>
#include <boost/shared_ptr.hpp>
#include <vector>

typedef std::vector< std::vector< std::bitset<11> > > FlagsVector;

namespace yarl
{
    namespace path
    {
        class Pathfinder;
    }

    namespace level
    {
        class LevelMap
        {
        // Member Variables
            private:
                int width, height;
                FlagsVector flags;

            public:
                boost::shared_ptr<path::Pathfinder> pathfinder;

        // Member Functions
            LevelMap(const int, const int);

            int getWidth() const {return width;}
            int getHeight() const {return height;}

            bool getFifthBit(const int x, const int y) const
            {
                return flags.at(x).at(y).test(5);
            }
        };



        class Level
        {
        // Member Variables
            public:
                LevelMap map;

        // Member Functions
            public:
                Level(const int w=50, const int h=50);
        };
    }


    namespace path
    {
        class Pathfinder
        {
        // Member Variables
            private:
                boost::shared_ptr<level::LevelMap> clientMap;

        // Member Functions
            public:
                Pathfinder() {}
                Pathfinder(level::LevelMap* cm)
                : clientMap(cm) {}

                void test() const;
        };
    }
}
从gdb回溯显示,非法指令位于编译器生成的
Pathfinder
析构函数中,该析构函数在销毁其共享的\u ptr时遇到问题。有人知道为什么吗

yarl::level::Level l;
实例化自动
级别
变量,该变量在其构造函数中构造其成员
pathfinder
,如下所示:

pathfinder(new path::Pathfinder(this))
然后在
Pathfinder
构造函数中,它获取您传入的
级别
指针,并将其分配给
共享的\u ptr
。然后,
shared_ptr
获得该指针的所有权

这是不正确的,原因如下:

  • 应使用
    共享\u ptr
    来管理动态分配的对象,而不是自动分配的对象
  • 如果你想使用
    shared\u ptr
    ,那么你应该在任何地方都使用它:就像现在一样,你将原始指针(例如传递给
    Pathfinder
    的构造函数,然后将它们存储为
    shared\u ptr
    s。这只会打开一个很大的所有权蠕虫
  • this
    分配给
    shared\u ptr
    的正确方法是从
    enable\u shared\u from\u this
    派生;但是请注意,在构造函数中无法从
    this
    获取
    shared\u ptr
  • 共享\u ptr
    被销毁时,它将尝试删除它管理的指针。但是,在这种情况下,该指针不是指向动态分配的对象(即,分配给
    新的
    ),而是指向自动分配的对象(即,在堆栈上)。因此,出现错误

    如果您不需要某些东西来获得资源的所有权,那么使用原始指针(或者引用,如果您有这个选项的话)没有什么错

    实例化自动
    级别
    变量,该变量在其构造函数中构造其成员
    pathfinder
    ,如下所示:

    pathfinder(new path::Pathfinder(this))
    
    然后在
    Pathfinder
    构造函数中,它获取您传入的
    级别
    指针,并将其分配给
    共享的\u ptr
    。然后
    共享的\u ptr
    获得该指针的所有权

    这是不正确的,原因如下:

  • 应使用
    共享\u ptr
    来管理动态分配的对象,而不是自动分配的对象
  • 如果你想使用
    shared\u ptr
    ,那么你应该在任何地方都使用它:就像现在一样,你将原始指针(例如传递给
    Pathfinder
    的构造函数,然后将它们存储为
    shared\u ptr
    s。这只会打开一个很大的所有权蠕虫
  • this
    分配给
    shared\u ptr
    的正确方法是从
    enable\u shared\u from\u this
    派生;但是请注意,在构造函数中无法从
    this
    获取
    shared\u ptr
  • 共享\u ptr
    被销毁时,它将尝试删除它管理的指针。但是,在这种情况下,该指针不是指向动态分配的对象(即,分配给
    新的
    ),而是指向自动分配的对象(即,在堆栈上)。因此,出现错误


    如果您不需要某些东西来获得资源的所有权,那么使用原始指针(或引用,如果您有该选项)没有什么错。

    您是从一个不应该由共享指针管理的指针构建
    共享指针。

    当最后一个共享的ptr副本被销毁时,该内存是空闲的—实际上它不应该是空闲的—在这种情况下,
    this
    在堆栈上

    shared_ptr
    的构造函数是显式的,这是有原因的——它正是为了避免从常规指针(不由shared_ptr管理)到共享_ptr的这种未被注意的转换——一旦你将这样的指针传递到shared_ptr,你的程序就注定了——唯一的出路是删除你不想要的指针删除


    一般来说,建议直接用new构造共享指针,例如
    ptr(newsomething(x,y,z)
    ),这样您就不会冒异常泄漏已分配但未分配到共享ptr内存的风险。

    您是从不应由共享ptr管理的指针构造
    共享ptr
    。(此
    指针)

    当最后一个共享的ptr副本被销毁时,该内存是空闲的—实际上它不应该是空闲的—在这种情况下,
    this
    在堆栈上

    shared_ptr
    的构造函数是显式的,这是有原因的——它正是为了避免从常规指针(不由shared_ptr管理)到共享_ptr的这种未被注意的转换——一旦你将这样的指针传递到shared_ptr,你的程序就注定了——唯一的出路是删除你不想要的指针删除


    通常,建议直接使用new构造共享指针,例如
    ptr(newsomething(x,y,z)
    -这样,您就不会冒异常泄漏已分配但未分配到共享\u ptr内存的风险。

    Level
    包含一个
    LevelMap
    成员变量。当
    Level
    被销毁时,它还将销毁其
    LevelMap

    另一方面,指向此
    LevelMap
    成员的指针被传递到
    Pathfinder
    ,这将从传递的指针创建一个
    shared\u ptr
    。这个新创建的
    shared\u ptr
    认为它拥有它所指向的对象,并将在
    Pathfinder
    被销毁后尝试销毁它

    因此,
    LevelMap
    被多次销毁

    在本例中,
    LevelMap
    是在堆栈上创建的。因此,
    shared\u pt调用
    delete
    pathfinder(new path::Pathfinder(this))