1

クラスのメンバーとしてポインタのリストがあります。そのクラスをインスタンス化すると、リストが空の場合、size()やempty()などのさまざまな関数がsegfaultで失敗します。リストに何かを追加すると、問題ありません。テストファイルで行っていることを抽象化しようとしましたが、完全に機能します。これは、コードが失敗したときに私がしていることだと思います(明らかにそうではありませんが):

#include <list>
#include <iostream>

class Test {
  int i;
};

int main() {
  std::list<Test*> tlist;

  if (tlist.empty()) {
    std::cout << "List empty";
  } else {
    std::cout << "List not empty";
  }
}

問題の原因となっているコードリスト全体を実際に投稿することはできません。これはかなり大きく、ファイルの束を超えているためですが、関連するすべてのビットをコードから直接貼り付けようとします。

player.hでのクラス宣言:

class Player : public ScreenObject {
private:
    std::list<Thing*> inventory;

コンストラクターでは、そのリストには何も行われません。

失敗している場所:

main.cpp:

Player pc(iname, w_choice, c_choice, 11, 11, WHITE, '@');

...。

if (pc.addToInv(t)) {
    currentLevel.delObject(id);
}

...。

player.cpp:

int Player::addToInv(Thing& t) {
    if (inventory.size() <= 52) {
        inventory.push_back(&t);
    } else {
        shiplog("Cannot add to inventory, 52 item limit reached",10);
        return 0;
    }
}

gdbで実行したときに発生するエラーは、size()の呼び出しで発生し、ここで終了します。

Program received signal SIGSEGV, Segmentation fault.
0x0804eda6 in std::_List_const_iterator<Thing*>::operator++ (this=0xbfff9500)
at /usr/include/c++/4.4/bits/stl_list.h:223
223            _M_node = _M_node->_M_next;

どんな推測でも大歓迎です!


完全なバックトレースは次のとおりです。

(gdb) bt
 0  0x0804e28a in std::_List_const_iterator<Thing*>::operator++ (
    this=0xbfff9500) at /usr/include/c++/4.4/bits/stl_list.h:223
 1  0x0804e64e in std::__distance<std::_List_const_iterator<Thing*> > (
    __first=..., __last=...)
    at /usr/include/c++/4.4/bits/stl_iterator_base_funcs.h:79
 2  0x0804e4d3 in std::distance<std::_List_const_iterator<Thing*> > (
    __first=..., __last=...)
    at /usr/include/c++/4.4/bits/stl_iterator_base_funcs.h:114
 3  0x0804e2e6 in std::list<Thing*, std::allocator<Thing*> >::size (
    this=0xbffff244) at /usr/include/c++/4.4/bits/stl_list.h:805
 4  0x0804df78 in Player::addToInv (this=0xbffff068, t=...) at player.cpp:551
 5  0x0804a873 in main (argc=1, argv=0xbffff494) at main.cpp:182
4

1 に答える 1

1
int Player::addToInv(Thing& t) {
if (inventory.size() <= 52) {
    inventory.push_back(&t);
} else {
    shiplog("Cannot add to inventory, 52 item limit reached",10);
    return 0;
}

}

Thingは参照によって渡されますが、そのアドレスは inventory.push_back() に渡されます。「t」だけを渡してみてください。

于 2013-02-15T17:47:09.433 に答える