Редактировать: Это оказалось проблемой во временном порядке. В принципе, я не знал использовать C++, как если бы он работал как Java или C#, чего нет. Надеюсь, это будет хороший предостерегающий рассказ.Boost Fusion контейнер общих указателей (shared_ptr), вызывающий ошибку сегментации (sigsegv) или результаты мусора
Редактировать: Эта проблема возникает только с комбинацией joint_view
и shared_ptr
. Очевидно, что исходные указатели работают в одном и том же сценарии, как и общие указатели в обычном контейнере слияния, сконструированном со всеми его элементами одновременно, не добавляя к нему ничего большего. Подробности ниже:
Я использую MinGW GCC 4.5.1 Запуск в своеобразный вопрос при использовании наддува фьюжн контейнера (ов) и получить содержимое обратно. У меня есть пользовательский класс, который обернут в std::shared_ptr
, тогда это передано fusion make_list()
(или make_vector()
, похоже, не имеет значения). Все хорошо, если я могу одновременно забрать все свои объекты в контейнер. Проблема, похоже, возникает, когда я добавляю еще один общий указатель на контейнер, который дает joint_view
. Я повторяю с помощью fusion::for_each()
и передаю объект функции, чтобы распечатать значение. Если я повторяю обычный контейнер слияния общих указателей вместо joint_view
или joint_view
без общих указателей в нем, он отлично работает, но в остальном - ошибки сегментации или значения мусора.
Ниже приведена тестовая программа, которую я сделал, чтобы попытаться изолировать мою проблему. Любые идеи о том, что может быть проблемой? Это вполне возможно, я просто не хватает что-то, что я должен/не должен делать :(
#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;
}
Правильно, я понимаю метод joint_view для хранения его элементов и полагаю, что я могу потерять временные ряды, но именно поэтому у меня так много тестов с использованием 'shared_ptr' чтобы обернуть элементы, входящие в контейнер. И снова, если я получу все предметы в контейнере за один раз и не использую 'push_back()', чтобы добавить что-либо, он отлично работает. Кроме того, если вы посмотрите на joint_view_test3, я не использую 'shared_ptr', но я добавляю еще один элемент, и он отлично работает. Это когда у меня есть контейнер 'shared_ptr' и добавьте еще что-то к нему, а затем подайте полученный файл joint_view в 'for_each(), что у меня проблемы. –
Что вы думаете? Для меня очевидно, что вы создаете временные разделы, которые привязаны к ссылкам внутри joint_view. Не пытайтесь сохранить файл joint_view, но напрямую передавайте его функции, которая должна что-то с ней делать. Это предотвратит слишком быстрое выключение временных рядов.Прочитайте в стандарте, если вы не знаете, как долго временные файлы хранятся в компиляторе (подсказка: обычно до следующей точки с запятой, но это только приблизительная оценка). – hkaiser
Похоже на то, что вы сказали немного ... Я добавил еще один тестовый пример, и это сработало, и я понимаю, почему это сработало, но я все еще немного потерян, поэтому, пожалуйста, несите меня. Да, я создавал temps, но обертывал их в интеллектуальные указатели и предоставлял их контейнеру слияния, сам по себе был temp. Но до того, как контейнер выходит из области видимости, я добавляю к нему еще одну ptr-wrapped temp, создавая 'joint_view', который содержит ссылки на ... мои умные указатели (мое предположение)? Или у него есть ссылки на элементы за моими умными указателями? Если он удаляет мои указатели, я понимаю, что мои объекты выходят за рамки. –