升压共享指针(shared_ptr的)导致分段错误(SIGSEGV)或无用结果的融合容器 [英] Boost Fusion container of shared pointers (shared_ptr) causing Segmentation Fault (sigsegv) or garbage results

查看:253
本文介绍了升压共享指针(shared_ptr的)导致分段错误(SIGSEGV)或无用结果的融合容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:这原来是用临时的问题。基本上,我是无知使用C ++,如果它的工作就像Java或C#,它没有。我们希望,这将是一个很好的警示。

编辑:这个问题似乎只与 joint_view 的shared_ptr 组合发生。裸指针似乎相同的情况下,以做工精细,在构建W /所有的项目在一次普通的融合容器做共享指针,无所添加到它。详情如下:

我使用MinGW的GCC 4.5.1
使用升压融合容器(S)和获取内容背出来,当运行到一个特殊的问题。我有一个自定义类,被包裹在一个的std :: shared_ptr的,那么这就是交给融合 make_list() (或 make_vector(),似乎并不重要)。一切都很好,如果我可以在同一时间得到所有我的对象的容器中。这个问题似乎来的时候我又共享指针添加到容器中,这将产生一个 joint_view 。我重复使用融合::的for_each()并传递一个函数对象打印出的值。如果我遍历共享指针,而不是一个简单的融合容器中的 joint_view joint_view 没有共享指针在它,它工作正常,但在其他方面,段故障或垃圾值。

下面是我做了尝试并隔离我的问题,一个测试程序。什么问题可能是任何想法?这是完全有可能的,我只是失去了一些东西,我应该/不应该做的:(

 的#include<&iostream的GT;
#包括LT&;内存和GT;// BOOST智能指针
//我只使用Boost的shared_ptr的对于一次测试,结果都一样。
#包括LT&;升压/ shared_ptr.hpp>
#包括LT&;升压/ make_shared.hpp>// BOOST FUSION
#包括LT&;升压/融合/算法/迭代/ for_each.hpp>
#包括LT&;升压/融合/有/ for_each.hpp>
#包括LT&;升压/融合/集装箱/生成/ make_list.hpp>
#包括LT&;升压/融合/有/ make_list.hpp>
#包括LT&;升压/融合/集装箱/生成/ make_vector.hpp>
#包括LT&;升压/融合/有/ make_vector.hpp>
#包括LT&;升压/融合/算法/改造/ push_back.hpp>
#包括LT&;升压/融合/有/ push_back.hpp>使用命名空间std;
使用空间boost ::融合;结构TestStructInt {
    INT test_int;    TestStructInt(INT init_num):test_int(init_num){};
};结构TestStructString {
    串test_string;    TestStructString(字符串init_str):test_string(init_str){};
};结构do_junk {
    void运算符()(串T)const的{
        COUT<< T<< ENDL;
    }    void运算符()(字符串* T)常量{
        COUT<< * T<< ENDL;
    }    void运算符()(STD :: shared_ptr的< INT>吨)const的{
        COUT<< * T<< ENDL;
    }    void运算符()(STD :: shared_ptr的<串GT;吨)const的{
        COUT<< * T<< ENDL;
    }    void运算符()(提高:: shared_ptr的<串GT;吨)const的{
        COUT<< * T<< ENDL;
    }    void运算符()(TestStructInt T)const的{
        COUT<< t.test_int<< ENDL;
    }    void运算符()(STD :: shared_ptr的< TestStructInt>吨)const的{
        COUT<< T-> test_int<< ENDL;
    }    void运算符()(TestStructString T)const的{
        COUT<< t.test_string<< ENDL;
    }    void运算符()(STD :: shared_ptr的< TestStructString>吨)const的{
        COUT<< T-> test_string<< ENDL;
    }    void运算符()(STD :: shared_ptr的< TestStructString *> T)const的{
        COUT<< (* T) - GT; test_string<< ENDL;
    }
};诠释的main()
{
    字符串foo1 =foo1;
    字符串foo2的=foo2的;
    字符串foo3 =foo3;
    INT BAR1 = 1;
    INT BAR2 = 2;
    INT bar3 = 3;
    字符串* foo1_ptr =安培; foo1;
    字符串* foo2_ptr =安培; foo2的;
    字符串* foo3_ptr =安培; foo3;
    自动foo1_obj = make_shared&所述; TestStructString>(TestStructString(foo1));
    汽车foo2_obj = make_shared< TestStructString>(TestStructString(foo2的));
    自动foo3_obj = make_shared&所述; TestStructString>(TestStructString(foo3));    //工作正常
    汽车list_test1 = make_list(foo1,foo2的);    //工作正常
    汽车list_test2 = make_list(foo1_ptr,foo2_ptr);    //似乎工作,但未定义行为
    汽车list_test3
        = make_list(
            的std :: make_shared< INT>(BAR1)的std :: make_shared< INT>(BAR2)
        )
    ;    //似乎工作,但未定义行为
    汽车list_test4
        = make_list(
            的std :: make_shared<串GT;(foo1)的std :: make_shared<串GT;(foo2的)
        )
    ;    //似乎工作,但未定义行为
    汽车list_test5
        = make_list(
            的std :: make_shared< TestStructInt>(TestStructInt(1))
            ,性病:: make_shared< TestStructInt>(TestStructInt(2))
        )
    ;    //似乎工作,但未定义行为
    汽车list_test6
        = make_list(
            的std :: make_shared< TestStructString>(TestStructString(foo1))
            ,性病:: make_shared< TestStructString>(TestStructString(foo2的))
        )
    ;    //似乎工作,但未定义行为
    汽车list_test7
        = make_list(TestStructString(foo1),TestStructString(foo2的))
    ;    //似乎工作,但未定义行为
    汽车joint_view_test1 =的push_back(make_list(foo1,foo2的),foo3);    //似乎工作,但未定义行为
    汽车joint_view_test2 =的push_back(make_list(foo1_ptr,foo2_ptr),foo3_ptr);    //似乎工作,但未定义行为
    汽车joint_view_test3
        =的push_back(
            make_list(
                TestStructString(foo1),TestStructString(foo2的)
            )
            ,TestStructString(foo3)
        )
    ;    //整数值我通过在正出来的不同
    汽车joint_view_test4
        =的push_back(
            make_list(
                的std :: make_shared< INT>(BAR1)的std :: make_shared< INT>(BAR2)
            )
            ,make_shared<&诠释GT;(bar3)
        )
    ;    //传递foo1和Foo2和foo3,但只得到foo3的价值背出每
    汽车joint_view_test5
        =的push_back(
            make_list(
                的std :: make_shared<串GT;(foo1)的std :: make_shared<串GT;(foo2的)
            )
            ,make_shared<串GT;(foo3)
        )
    ;    //运行do_junk时,导致赛格故障()
    汽车joint_view_test6
        =的push_back(
            make_vector(
                的std :: make_shared<串GT;(foo1)的std :: make_shared<串GT;(foo2的)
            )
            ,性病:: make_shared<串GT;(foo3)
        )
    ;    //运行do_junk时,导致赛格故障()
    汽车joint_view_test7
        =的push_back(
            make_list(
                提高:: make_shared<串GT;(foo1)
                ,提振:: make_shared<串GT;(foo2的)
            )
            ,提振:: make_shared<串GT;(foo3)
        )
    ;    //整数值我通过在正出来的不同
    汽车joint_view_test8
        =的push_back(
            make_list(
                的std :: make_shared< TestStructInt>(TestStructInt(1))
                ,性病:: make_shared< TestStructInt>(TestStructInt(2))
            )
            ,性病:: make_shared< TestStructInt>(TestStructInt(3))
        )
    ;    //运行do_junk时,导致赛格故障()
    汽车joint_view_test9
        =的push_back(
            make_list(
                的std :: make_shared< TestStructString>(TestStructString(foo1))
                ,性病:: make_shared< TestStructString>(TestStructString(foo2的))
            )
            ,性病:: make_shared< TestStructString>(TestStructString(foo3))
        )
    ;    //运行do_junk时,导致赛格故障()
    汽车joint_view_test10
        =的push_back(
            make_list(
                的std :: make_shared< TestStructString *>(新TestStructString(foo1))
                ,性病:: make_shared< TestStructString *>(新TestStructString(foo2的))
            )
            ,性病:: make_shared< TestStructString *>(新TestStructString(foo3))
        )
    ;    //似乎工作,但未定义行为
    汽车joint_view_test11
        =的push_back(
            make_list(
                foo1_obj
                ,foo2_obj
            )
            ,foo3_obj
        )
    ;    COUT<< @@ list1的<< ENDL;
    提高::融合:: for_each的(list_test1,do_junk());
    COUT<< @@列表2<< ENDL;
    提高::融合:: for_each的(list_test2,do_junk());
    COUT<< @@项目list3<< ENDL;
    提高::融合:: for_each的(list_test3,do_junk());
    COUT<< @@ list4<< ENDL;
    提高::融合:: for_each的(list_test4,do_junk());
    COUT<< @@ list5<< ENDL;
    提高::融合:: for_each的(list_test5,do_junk());
    COUT<< @@ list6<< ENDL;
    提高::融合:: for_each的(list_test6,do_junk());
    COUT<< @@ list7<< ENDL;
    提高::融合:: for_each的(list_test7,do_junk());
    COUT<< @@ joint_view1<< ENDL;
    提高::融合:: for_each的(joint_view_test1,do_junk());
    COUT<< @@ joint_view2<< ENDL;
    提高::融合:: for_each的(joint_view_test2,do_junk());
    COUT<< @@ joint_view3<< ENDL;
    提高::融合:: for_each的(joint_view_test3,do_junk());
    COUT<< @@ joint_view4<< ENDL;
    提高::融合:: for_each的(joint_view_test4,do_junk());
    COUT<< @@ joint_view5<< ENDL;
    //提振::融合:: for_each的(joint_view_test5,do_junk());
    COUT<< @@ joint_view6<< ENDL;
    //提振::融合:: for_each的(joint_view_test6,do_junk());
    COUT<< @@ joint_view7<< ENDL;
    //提振::融合:: for_each的(joint_view_test7,do_junk());
    COUT<< @@ joint_view8<< ENDL;
    //提振::融合:: for_each的(joint_view_test8,do_junk());
    COUT<< @@ joint_view9<< ENDL;
    //提振::融合:: for_each的(joint_view_test9,do_junk());
    COUT<< @@ joint_view10<< ENDL;
    //提振::融合:: for_each的(joint_view_test10,do_junk());
    COUT<< @@ joint_view11<< ENDL;
    提高::融合:: for_each的(joint_view_test11,do_junk());
    COUT<< @@<< ENDL;    返回0;
}


解决方案

融合:: joint_view 持有到它的元素引用。你必须非常小心,它并不是指临时(他们将在iteraton时间在你的设置可以超出范围)。这似乎是在实施例的情况。

Edit: This turned out to be an issue with temporaries. Basically, I was ignorantly using C++ as if it worked like Java or C#, which it does not. Hopefully, this will be a good cautionary tale.

Edit: This issue only seems to happen with the combination of joint_view and shared_ptr. Raw pointers seem to work fine in the same scenario, as do shared pointers in a plain fusion container constructed w/ all its items at once, without adding anything more to it. Details below:

I'm using mingw gcc 4.5.1 Running into a peculiar issue when using boost fusion container(s) and getting contents back out. I have a custom class that gets wrapped in a std::shared_ptr, then that's handed to a fusion make_list() (or make_vector(), doesn't seem to matter). All is well if I can get all of my objects into the container at one time. The problem seems to come up when I add another shared pointer to the container, which yields a joint_view. I iterate using a fusion::for_each() and pass in a function object to print out the value. If I'm iterating a plain fusion container of shared pointers instead of a joint_view, or a joint_view with no shared pointers in it, it works fine, but otherwise, segmentation fault or garbage values.

Below is a test program I made to try and isolate my problem. Any ideas on what the issue may be? It's entirely possible I'm just missing something that I should/shouldn't be doing :(

#include <iostream>
#include <memory>

//BOOST SMART POINTERS
//I only use boost's shared_ptr for ONE test, results are the same.
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

//BOOST FUSION
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/container/generation/make_list.hpp>
#include <boost/fusion/include/make_list.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/algorithm/transformation/push_back.hpp>
#include <boost/fusion/include/push_back.hpp>

using namespace std;
using namespace boost::fusion;

struct TestStructInt {
    int test_int;

    TestStructInt(int init_num) : test_int(init_num) {};
};

struct TestStructString {
    string test_string;

    TestStructString(string init_str) : test_string(init_str) {};
};

struct do_junk{
    void operator()(string t) const {
        cout << t << endl;
    }

    void operator()(string* t) const {
        cout << *t << endl;
    }

    void operator()(std::shared_ptr<int> t) const {
        cout << *t << endl;
    }

    void operator()(std::shared_ptr<string> t) const {
        cout << *t << endl;
    }

    void operator() (boost::shared_ptr<string> t) const {
        cout << *t << endl;
    }

    void operator() (TestStructInt t) const {
        cout << t.test_int << endl;
    }

    void operator() (std::shared_ptr<TestStructInt> t) const {
        cout << t->test_int << endl;
    }

    void operator() (TestStructString t) const {
        cout << t.test_string << endl;
    }

    void operator() (std::shared_ptr<TestStructString> t) const {
        cout << t->test_string << endl;
    }

    void operator() (std::shared_ptr<TestStructString*> t) const {
        cout << (*t)->test_string << endl;
    }
};

int main()
{
    string foo1 = "foo1";
    string foo2 = "foo2";
    string foo3 = "foo3";
    int bar1 = 1;
    int bar2 = 2;
    int bar3 = 3;
    string* foo1_ptr = &foo1;
    string* foo2_ptr = &foo2;
    string* foo3_ptr = &foo3;
    auto foo1_obj = make_shared<TestStructString>(TestStructString("foo1"));
    auto foo2_obj = make_shared<TestStructString>(TestStructString("foo2"));
    auto foo3_obj = make_shared<TestStructString>(TestStructString("foo3"));

    //works fine
    auto list_test1 = make_list(foo1, foo2);

    //works fine
    auto list_test2 = make_list(foo1_ptr, foo2_ptr);

    //seems to work, but is undefined behavior
    auto list_test3
        = make_list(
            std::make_shared<int>(bar1), std::make_shared<int>(bar2)
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test4
        = make_list(
            std::make_shared<string>(foo1), std::make_shared<string>(foo2)
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test5
        = make_list(
            std::make_shared<TestStructInt>(TestStructInt(1))
            , std::make_shared<TestStructInt>(TestStructInt(2))
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test6
        = make_list(
            std::make_shared<TestStructString>(TestStructString("foo1"))
            , std::make_shared<TestStructString>(TestStructString("foo2"))
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test7
        = make_list(TestStructString("foo1"), TestStructString("foo2"))
    ;

    //seems to work, but is undefined behavior
    auto joint_view_test1 = push_back(make_list(foo1, foo2), foo3);

    //seems to work, but is undefined behavior
    auto joint_view_test2 = push_back(make_list(foo1_ptr, foo2_ptr), foo3_ptr);

    //seems to work, but is undefined behavior
    auto joint_view_test3
        = push_back(
            make_list(
                TestStructString(foo1), TestStructString(foo2)
            )
            , TestStructString(foo3)
        )
    ;

    //integer values I pass in are coming out different
    auto joint_view_test4
        = push_back(
            make_list(
                std::make_shared<int>(bar1), std::make_shared<int>(bar2)
            )
            , make_shared<int>(bar3)
        )
    ;

    //pass in foo1, foo2, and foo3, but only get foo3's value back out for each
    auto joint_view_test5
        = push_back(
            make_list(
                std::make_shared<string>(foo1), std::make_shared<string>(foo2)
            )
            , make_shared<string>(foo3)
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test6
        = push_back(
            make_vector(
                std::make_shared<string>(foo1), std::make_shared<string>(foo2)
            )
            , std::make_shared<string>(foo3)
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test7
        = push_back(
            make_list(
                boost::make_shared<string>(foo1)
                , boost::make_shared<string>(foo2)
            )
            , boost::make_shared<string>(foo3)
        )
    ;

    //integer values I pass in are coming out different
    auto joint_view_test8
        = push_back(
            make_list(
                std::make_shared<TestStructInt>(TestStructInt(1))
                , std::make_shared<TestStructInt>(TestStructInt(2))
            )
            , std::make_shared<TestStructInt>(TestStructInt(3))
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test9
        = push_back(
            make_list(
                std::make_shared<TestStructString>(TestStructString("foo1"))
                , std::make_shared<TestStructString>(TestStructString("foo2"))
            )
            , std::make_shared<TestStructString>(TestStructString("foo3"))
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test10
        = push_back(
            make_list(
                std::make_shared<TestStructString*>(new TestStructString("foo1"))
                , std::make_shared<TestStructString*>(new TestStructString("foo2"))
            )
            , std::make_shared<TestStructString*>(new TestStructString("foo3"))
        )
    ;

    //seems to work, but is undefined behavior
    auto joint_view_test11
        = push_back(
            make_list(
                foo1_obj
                , foo2_obj
            )
            , foo3_obj
        )
    ;

    cout << "@@ list1" << endl;
    boost::fusion::for_each(list_test1, do_junk());
    cout << "@@ list2" << endl;
    boost::fusion::for_each(list_test2, do_junk());
    cout << "@@ list3" << endl;
    boost::fusion::for_each(list_test3, do_junk());
    cout << "@@ list4" << endl;
    boost::fusion::for_each(list_test4, do_junk());
    cout << "@@ list5" << endl;
    boost::fusion::for_each(list_test5, do_junk());
    cout << "@@ list6" << endl;
    boost::fusion::for_each(list_test6, do_junk());
    cout << "@@ list7" << endl;
    boost::fusion::for_each(list_test7, do_junk());
    cout << "@@ joint_view1" << endl;
    boost::fusion::for_each(joint_view_test1, do_junk());
    cout << "@@ joint_view2" << endl;
    boost::fusion::for_each(joint_view_test2, do_junk());
    cout << "@@ joint_view3" << endl;
    boost::fusion::for_each(joint_view_test3, do_junk());
    cout << "@@ joint_view4" << endl;
    boost::fusion::for_each(joint_view_test4, do_junk());
    cout << "@@ joint_view5" << endl;
    //boost::fusion::for_each(joint_view_test5, do_junk());
    cout << "@@ joint_view6" << endl;
    //boost::fusion::for_each(joint_view_test6, do_junk());
    cout << "@@ joint_view7" << endl;
    //boost::fusion::for_each(joint_view_test7, do_junk());
    cout << "@@ joint_view8" << endl;
    //boost::fusion::for_each(joint_view_test8, do_junk());
    cout << "@@ joint_view9" << endl;
    //boost::fusion::for_each(joint_view_test9, do_junk());
    cout << "@@ joint_view10" << endl;
    //boost::fusion::for_each(joint_view_test10, do_junk());
    cout << "@@ joint_view11" << endl;
    boost::fusion::for_each(joint_view_test11, do_junk());
    cout << "@@" << endl;

    return 0;
}

解决方案

fusion::joint_view is holding on to it's elements as references. You need to be very careful it does not refer to temporaries (they would be gone out of scope at iteraton time in your setup). This seems to be the case in your examples.

这篇关于升压共享指针(shared_ptr的)导致分段错误(SIGSEGV)或无用结果的融合容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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