1

luabind を使用して stl::vector::iterator を lua スクリプトに返すときに奇妙な問題が発生しました。

以下はコードです:

1) lua スクリプトによって呼び出される 2 つの関数を作成しました。

std::vector<car*> get_car_list()
{
    std::vector<car*>* vec = new std::vector<car*>();
    vec->push_back(new car("I'm the 1st"));
    vec->push_back(new car("I'm the 2nd")); 
    return *vec;
}

void output(const std::string& msg)
{
    std::cout << "lua:" << msg << std::endl;
}

2) 関数を lua にバインドします

luabind::module(L)
[
    luabind::def("get_car_list", &get_car_list, luabind::return_stl_iterator)
];

luabind::module(L)
[
    luabind::def("output", &output)
];

3) 以下のようなスクリプトを実行します。

function test()
    items  = get_car_list();
    for item in items do
        output(item:get_name());
    end
end

4)結果は次のとおりです。出力ウィンドウには、次のように表示されます。

lua:I'm the 1st

そして、プログラムは luabind/policy.hpp:754 で壊れています

template <>
struct default_converter<std::string>
  : native_converter_base<std::string>
{
    .....

    void to(lua_State* L, std::string const& value)
    {
        lua_pushlstring(L, value.data(), value.size()); // !!Break Here with Error EXC_BAD_ACCESS
    }
};

std::vector のすべての要素を表示したいのですが、最初の要素しか表示されずにクラッシュします。

どうもありがとうございます!:)

ジェイソン

4

1 に答える 1

3

2 つの問題があります。

Java の場合のようにポインターと new を使用しますが、それは C++ です。このように C++ を使用すると、明らかなメモリ リークが発生します。

特別な理由がある場合を除き、次のようにする必要があります。

std::vector<car> get_car_list() {
    std::vector<car> vec;
    vec->push_back( car("I'm the 1st"));
    vec->push_back( car("I'm the 2nd")); 
    return vec; }

しかし、コードの 2 番目の問題に入ります。

return_stl_iterator は、使用時に stl コンテナーがまだ存在していると想定し、イテレーターをこのコンテナーにのみ格納するようです。

イテレータを使用するときにコンテナが存在しなくなるため、コンテナのコピーを返すことはできません。一時的なコンテナへの参照を使用している場合と似ています。

この例のluabind docに見られるように、return_stl_iteratorのアイデアは、引き続きアクセス可能なコンテナーを持つことです。この例では、コンテナーは構造体に存在します。一時的なものではありません。

ベクターを new で割り当て、get_car_list 関数でこのベクターへの参照を返したいと思うかもしれません。しかし、これをしないでください: いつコンテナを解放しますか?

他の場所に存在しないベクトル (ベクトルの一時的なコピー) を返したい場合は、return_stl_iterator ポリシーを使用しないでください。このために作成されていないようです。

于 2011-09-13T05:50:23.597 に答える