2

テンプレート化された静的クラスを使用してリソース (画像、フォント、メッシュ データなど) の管理を処理するコードがいくつかあり、クライアント コードは次のようなことを実行できます。

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への呼び出しでセグメンテーション違反が発生することです。ただし、代わりに、挿入操作 ( から発生) またはへの呼び出し(から発生) でsegfault を取得します。findfind_iteratorstd::map_Rb_tree_decrementfindstring::compare

この問題は、リソースが2回要求されたときにのみ発生します (失敗が発生した場合、fileName は有効です)。

これは両方で起こっているmapのでunordered_map、これを引き起こすにはどこかで奇妙なことをしているに違いないと思います。何かアイデアはありますか?

ありがとう。

編集:まだ問題がありますが、リソースが2回目にリクエストされたときにのみ発生するというのは間違っていました。ただし、リソースを取得するための最初の 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
4

3 に答える 3

2

明らかなエラーを見つけることができません。Valgrindを試しましたか(ある種の* nixシステムを実行していると仮定します)?これはメモリエラーを見つけるための非常に貴重なツールであり、これはその1つである可能性があります。

于 2010-07-08T02:48:14.620 に答える
0

リソースが 2 回目に要求されたときにのみ問題が発生する

これは、コードがリソースを解放している可能性があることを示唆しています-最初はすべて問題なく、次に解放し、次にコンテナーがそのメモリにアクセスしようとすると、セグメンテーション違反が発生します。

于 2010-07-08T02:45:18.170 に答える