使用std :: map / boost :: unordered_map帮助理解segfault [英] Help understanding segfault with std::map/boost::unordered_map

查看:416
本文介绍了使用std :: map / boost :: unordered_map帮助理解segfault的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

资源类型必须有一个构造函数,并带有 const std ::



getResource 实现如下:

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

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;
}

返回资源;
}

as typedef typename boost :: unordered_map< std :: string,boost :: shared_ptr< ResourceType> > table_t;



_resources 的类型为 table_t



问题是 boost :: unordered_map 我得到一个segfault find (源自 find_iterator )。然而,使用 std :: map ,我得到一个segfault插入操作(源自 _Rb_tree_decrement ),或调用 find (源自 string :: compare )。



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



这是发生在 map unordered_map 我假设我必须做某事



编辑:仍然有问题,我是错了只有第二次请求资源时才发生。然而,获得资源的前2个调用是成功的,它是导致segfault的第三个调用(每个调用是针对不同的资源)。



这里是堆栈跟踪:

 编程接收信号SIGSEGV,分段故障。 
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_; boost :: unordered_detail :: hash_table< boost :: unordered_detail :: map< std :: string,boost :: hash< std :: string>中的
(gdb)bt
#0 0x00000000004b4978,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在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在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在地图(这= = 0x7fffffffdfc0,fileName = ...)在/ 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在Main :: run(xResolution = 1024,yResolution = 768)在/home/tim/Projects/gameproj/app/Main.cpp:28
#9 0x0000000000487db5在main(argc = 1,argv = 0x7fffffffe398)at /home/tim/Projects/gameproj/app/main.cpp :10


解决方案

您是否尝试过 Valgrind (假设您运行某种* nix系统)?这是一个找到内存错误的非常宝贵的工具,这看起来可能是其中之一。


I have some code to handle resource (images, fonts, mesh data, etc.) management using a template'd static class, allowing client code to do something like:

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();

The "resource type" must have a constructor taking a const std::string&.

getResource is implemented as follows:

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 is defined as typedef typename boost::unordered_map< std::string, boost::shared_ptr<ResourceType> > table_t;

_resources is of type table_t.

The problem is with boost::unordered_map I get a segfault on the call to find (originating from find_iterator). However, with std::map instead, I either get a segfault on the insert operation (originating from _Rb_tree_decrement), or on the call to find (originating from string::compare).

The problem only occurs the 2nd time a resource is requested (fileName is valid when the failure occurs).

As this is happening with both map and unordered_map I'm assuming I must be doing something bizarre somewhere to cause this, any ideas?

Thanks.

EDIT: Still having the problem, I was wrong about it only happening the 2nd time a resource is requested. However, the first 2 calls to get a resource are successful, it's the 3rd call that is causing the segfault (each call is for a different resource).

Here is a stack trace:

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

解决方案

I can't spot any obvious errors, have you tried Valgrind (assuming you run some kind of *nix system)? It's an invaluable tool for finding memory errors, and this looks like it might be one of those.

这篇关于使用std :: map / boost :: unordered_map帮助理解segfault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆