使用std :: map / boost :: unordered_map帮助理解segfault

时间:2010-07-08 02:40:51

标签: c++ boost map segmentation-fault unordered-map

我有一些代码来处理使用模板静态类的资源(图像,字体,网格数据等)管理,允许客户端代码执行以下操作:

ResourceManager<Texture>::init("data/textures");
ResourceManager<Font>::init("data/fonts");
// later ...
boost::shared_ptr<const Texture> tex = ResourceManager<Texture>::getResource("wall.png");
boost::shared_ptr<const Font> font = ResourceManager<Font>::getResource("Arial.ttf");
// later ...
ResourceManager<Texture>::release();

“资源类型”必须有一个const std::string&的构造函数。

getResource的实施方式如下:

static boost::shared_ptr<const ResourceType> getResource(const std::string& fileName)
{
    boost::shared_ptr<ResourceType> resource;

    typename table_t::const_iterator itr = _resources.find(fileName);
    if (itr == _resources.end()) {
        resource.reset(new ResourceType(_dataDirectory + fileName));
        _resources[fileName] = resource;
    } else {
        resource = itr->second;
    }

    return resource;
}

table_t定义为typedef typename boost::unordered_map< std::string, boost::shared_ptr<ResourceType> > table_t;

_resources的类型为table_t

问题在于boost::unordered_map我在调用find时遇到了段错误(来自find_iterator)。但是,使用std::map代替,我会在插入操作(源自_Rb_tree_decrement)或调用find(源自string::compare)时获得段错误。< / p>

问题只发生在第二次请求资源时(发生故障时fileName有效)。

正如mapunordered_map所发生的那样,我假设我必须做某些奇怪的事情来引起这个,任何想法?

感谢。

编辑:仍然遇到问题,我错了,它只发生在第二次请求资源时。但是,获得资源的前2次调用是成功的,这是导致段错误的第3次调用(每次调用都是针对不同的资源)。

这是一个堆栈跟踪:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004b4978 in boost::unordered_detail::hash_table<boost::unordered_detail::map<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, boost::shared_ptr<Texture> > > > >::find_iterator (this=0x7aed80, bucket=0x38, k=...)
    at /usr/local/include/boost/unordered/detail/table.hpp:55
55          node_ptr it = bucket->next_;
(gdb) bt
#0  0x00000000004b4978 in boost::unordered_detail::hash_table<boost::unordered_detail::map<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, boost::shared_ptr<Texture> > > > >::find_iterator (this=0x7aed80, bucket=0x38, k=...)
    at /usr/local/include/boost/unordered/detail/table.hpp:55
#1  0x00000000004b294c in boost::unordered_detail::hash_table<boost::unordered_detail::map<std::string, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, boost::shared_ptr<Texture> > > > >::find (this=0x7aed80, k=...)
    at /usr/local/include/boost/unordered/detail/table.hpp:583
#2  0x00000000004b07c1 in boost::unordered_map<std::string, boost::shared_ptr<Texture>, boost::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, boost::shared_ptr<Texture> > > >::find (this=0x7aed80, k=...)
    at /usr/local/include/boost/unordered/unordered_map.hpp:423
#3  0x00000000004ae7c6 in ResourceManager<Texture>::getResource (fileName=...) at /home/tim/Projects/gameproj/app/ResourceManager.hpp:52
#4  0x00000000004ce7fc in Map::loadCellTextures (this=0x7fffffffdfc0, in=...) at /home/tim/Projects/gameproj/app/Map.cpp:57
#5  0x00000000004ce632 in Map (this=0x7fffffffdfc0, fileName=...) at /home/tim/Projects/gameproj/app/Map.cpp:30
#6  0x0000000000495702 in Game::init (xResolution=1024, yResolution=768) at /home/tim/Projects/gameproj/app/Game.cpp:116
#7  0x0000000000494fa0 in Game::run (xResolution=1024, yResolution=768) at /home/tim/Projects/gameproj/app/Game.cpp:38
#8  0x0000000000487f1d in Main::run (xResolution=1024, yResolution=768) at /home/tim/Projects/gameproj/app/Main.cpp:28
#9  0x0000000000487db5 in main (argc=1, argv=0x7fffffffe398) at /home/tim/Projects/gameproj/app/main.cpp:10

3 个答案:

答案 0 :(得分:2)

我无法发现任何明显的错误,你试过Valgrind(假设你运行某种* nix系统)?它是查找内存错误的宝贵工具,看起来它可能就是其中之一。

答案 1 :(得分:0)

  

问题仅在第二次请求资源时发生

这告诉我你的代码可能正在释放资源 - 第一次一切正常,然后你释放它,然后下次容器试图访问那个内存时,就会发生段错误。

答案 2 :(得分:0)

看,我遇到了类似的问题。 我的班级在BlackBerry的编译器和qmake 4上工作得很好。但在qtcreator 5(64和32b)上,我遇到了同样的问题。 我跟踪了这​​个 http://www.instructables.com/answers/Why-would-an-empty-stdmap-seg-fault-on-the-first/#CXBBGN4GQO92M2Q

看起来默认构造函数在某些编译器上没有正确初始化。 我在父类构造函数上添加了clear(),现在似乎可以工作。

如果你有一些静态声明(或更糟的extern),并且实例化地图的时间不是预期的,也会发生这种情况。

我希望它有所帮助。