C++ &引用;地址不来自malloc();使用电子围栏时出错
我一直在写一个测试用例程序来演示我的一个更大的程序的问题, 而且测试用例有一个原始程序没有的bug 下面是头文件: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<
// 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))