Segfault with boost variant - c++

I've started to build up a little data type and at the current stage I have only one recursive type in a boost variant. It turns out, I get a segfault when I try to instantiate my type. If I put a string before the recursive type it works, putting it after the type it doesn't. I'm using mingw with gcc 4.8.1 64bit and boost 1.54.
Am I using boost variant the wrong way?
#include <boost/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <string>
#include <iostream>
struct A;
struct B;
using C = boost::variant<boost::recursive_wrapper<A>>;
// works:
// using C = boost::variant<std::string, boost::recursive_wrapper<A>>;
struct A {
std::string name;
C variant;
};
struct B {
std::string name;
C variant;
};
int main() {
std::cout << "start" << std::endl;
B hAST; // <--- segfaults
std::cout << "end" << std::endl;
return 0;
}

I believe this is due to the "never-empty" guarantee of variant: The default constructor of C must initialize itself with a default-constructed value of its first template parameter - which is recursive_wrapper<A> - and the default constructor of recursive_wrapper<A> must initialize itself with a default-constructed instance of A, which leads to infinite recursion.
Assuming you actually want a variant that is either empty, or an instance of A, you could introduce a dummy type as the variant's first parameter, for example:
struct variant_is_empty { };
using C = boost::variant<variant_is_empty, boost::recursive_wrapper<A>>;
EDIT: It appears you can use boost::recursive_wrapper with boost::optional, which would be easier than using variant for the above case of an optional, recursive type.

Related

Using a big struct as parameter with std async causes bug

I have a big struct that needs to be processed. So I use std async to do it on another thread. Here is a simple example below:
#include <iostream>
#include <future>
using namespace std;
struct teststruct{
float thisvalue[32][32][64];
};
void foo(teststruct thisdummy) {
this_thread::sleep_for(chrono::milliseconds(234));
cout << "hello";
}
int main() {
teststruct thisteststruct;
foo(thisteststruct); // this does work
auto futurevalue = async(launch::async, foo, thisteststruct); //this doesnt work
return 0;
}
I have a struct that is just a big 3d array of floats. When I run this I get an error saying Bus error: 10. Just calling foo without using async works but using std async it doesn't work. Somehow it is related with the struct size since when I make the struct
struct teststruct{
float thisvalue[32][32][63];
};
it magically works. I have tried splitting up the struct by half so a 32x32x32 array instead of a 32x32x64 array and taking in teststructs as parameters but it doesn't work. As I said above I think this has to do with the size of the struct. How can I fix this?
You are probably blowing the stack.
sizeof(teststruct) is 32*32*64*sizeof(float). Assuming a 4-byte float, that's 256KB that you are attempting to pass by value into foo.
While there are flags you can pass to the compiler to increase stack size, you really want to avoid passing large objects by value. As that requires an in-memory copy to be made. Pass that big struct by shared_pointer. That will enable it to be passed around on the main thread and on the async thread without using any significant amount of stack memory. It's also faster since it avoids the large copy of that object.
#include <iostream>
#include <future>
#include <memory>
using namespace std;
struct teststruct{
float thisvalue[32][32][64];
};
void foo(shared_ptr<teststruct> thisdummy) {
this_thread::sleep_for(chrono::milliseconds(234));
cout << "hello";
}
int main() {
auto thisteststruct = make_shared<teststruct>();
foo(thisteststruct);
auto futurevalue = async(launch::async, foo, thisteststruct);
return 0;
}
Making it a pointer or reference should do the trick.
(untested)
void foo(teststruct *thisdummy) {
this_thread::sleep_for(chrono::milliseconds(234));
cout << "hello";
}
int main() {
teststruct thisteststruct;
foo(&thisteststruct); // this does work
auto futurevalue = async(launch::async, foo, &thisteststruct); //this doesnt work
futurevalue.get();
return 0;
}
What the below discussion is about is:
If the std::future obtained from std::async is not moved from or bound
to a reference, the destructor of the std::future will block at the
end of the full expression until the asynchronous operation completes,
essentially making code such as the following synchronous:
See this

Filing a vector outside of a function in a class

Fairly simple question here, whats the best way to fill a vector outside of a function in a class .cpp file? currently i'm attempting the following which is not working:
std::vector<Player> midfielder(8);
midfielder.at(0) = Midfielder("Default ",0,"Midfielder");
midfielder.at(1) = Midfielder("David Armitage ",1,"Midfielder");
midfielder.at(2) = Midfielder("Tom Rockliff ",2,"Midfielder");
midfielder.at(3) = Midfielder("Gary Ablett ",3,"Midfielder");
midfielder.at(4) = Midfielder("Dyson Heppel ",4,"Midfielder");
midfielder.at(5) = Midfielder("Scott Pendlebury",5,"Midfielder");
midfielder.at(6) = Midfielder("Michael Barlow ",6,"Midfielder");
midfielder.at(7) = Midfielder("Jack Steven ",7,"Midfielder");
To provide context, 'Midfielder' is a class that inherits from the 'Player' class.
TeamManagment.h
#ifndef TEAMMANAGEMENT_H
#define TEAMMANAGEMENT_H
#include <vector>
#include "Player.h"
#include "Midfielder.h"
#include <string>
class TeamManagement
{
public:
TeamManagement();
void Display_Players();
};
#endif // TEAMMANAGEMENT_H
TeamManagement.cpp
#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
#include "Midfielder.h"
#include "TeamManagement.h"
using namespace std;
TeamManagement::TeamManagement()
{
}
std::vector<Player> midfielder(8);
//errors start occurring on line below: 'midfielder' does not name a type
midfielder.at(0) = Midfielder("Default ",0,"Midfielder");
midfielder.at(1) = Midfielder("David Armitage ",1,"Midfielder");
midfielder.at(2) = Midfielder("Tom Rockliff ",2,"Midfielder");
midfielder.at(3) = Midfielder("Gary Ablett ",3,"Midfielder");
midfielder.at(4) = Midfielder("Dyson Heppel ",4,"Midfielder");
midfielder.at(5) = Midfielder("Scott Pendlebury",5,"Midfielder");
midfielder.at(6) = Midfielder("Michael Barlow ",6,"Midfielder");
midfielder.at(7) = Midfielder("Jack Steven ",7,"Midfielder");
//errors stop occurring here
void TeamManagement::Display_Players(){
cout<<"Position Name ID"<<endl;
for (int i=1;i<8;i++)
{
cout<<midfielder[i].Player_Details()<<" "<<midfielder[i].Get_player_id()<<endl;
}
}
The first problem is that you cannot perform assignment like that outside of a function. You must use construction or initialization.
With C++98 you cannot populate/initialize a vector outside of a function.
With C++11/14 you can populate one using initializer syntax:
#include <iostream>
#include <vector>
struct Thing {
int m_i, m_j;
Thing(int i, int j) : m_i(i), m_j(j) {}
};
std::vector<Thing> things {
{ 1, 2 }, { 2, 3 }
};
int main() {
std::cout << "things[0].m_j = " << things[0].m_j << '\n';
}
But std::vector won't like you trying to put "Midfielder"s into a vector of Player. Lets use an SSCCE to reconstruct the damage you're doing:
#include <iostream>
struct Base {
int i;
};
struct Derived : public Base {
int j;
};
int main() {
std::cout << "Base size = " << sizeof(Base) << '\n';
std::cout << "Derived size = " << sizeof(Derived) << '\n';
}
This tells us that Base and Derived have a different size. But you're trying to put these two objects into the same container because they're related. Round peg and square peg are related... They won't fit into the same hole, and this is the problem we have now.
The vector creates space in memory for your elements based on the type you supply, and then it requires you to pass it exactly that type to populate those spaces with, or a type that has a conversion mechanism to the storage type.
If you want to have a container of different types, you'll need to use pointers, but then you're going to run into the problem that what you get back will be a pointer to the base type and you will need to provide yourself with a way to distinguish different player types.
See Store derived class objects in base class variables for the C++98 approach. In modern C++ (11 and 14) you should use smart pointers, e.g.
std::vector<std::unique_ptr<Base>>
std::vector<std::shared_ptr<Base>>
Presumably default constructing a Midfielder doesn't make a lot of sense, so you can reserve the memory, then emplace_back into the vector.
std::vector<Player> midfielder {};
midfielder.reserve(8);
midfielder.emplace_back("Default ",0,"Midfielder");
midfielder.emplace_back("David Armitage ",1,"Midfielder");
midfielder.emplace_back("Tom Rockliff ",2,"Midfielder");
midfielder.emplace_back("Gary Ablett ",3,"Midfielder");
midfielder.emplace_back("Dyson Heppel ",4,"Midfielder");
midfielder.emplace_back("Scott Pendlebury",5,"Midfielder");
midfielder.emplace_back("Michael Barlow ",6,"Midfielder");
midfielder.emplace_back("Jack Steven ",7,"Midfielder");
midfielder.at(0) = Midfielder("Default ",0,"Midfielder"); is a statement. You've put that and similar statements in (global) namespace scope. That's your bug. Only declarations may be in namespace scope. You must put your statements inside a function.
The error message stems from the fact that declarations which don't start with a keyword start with a type name. Since midfielder is not a keyword, the compiler expects it to be a type name but it isn't one, so you get the error.

C++ - How to Make Static Dictionary to Lookup Matrix

I am trying to write a C++ class that allows me to access certain matrix elements by a string lookup. I wanted to create a 'static' class that can do this, such as:
#include <unordered_map>
namespace Mine {
static double AA[3][4] = {
{5.04964676394959,-0.693207030363152,0.0422140829479668,-0.000968959310672217},
{2.6044054979329,0.288475262243944,-0.0208805589126506,0.000380899394040856},
{-4.32707864788065,1.07090008760872,-0.0777874445746693,0.00165150952598117}
};
static unordered_map<std::string, double[3][4]> Mine::parameter_store = { {"AA", AA}};
With the idea being that I would have several matrices, and could look them up based on a key. However, this seems to totally and utterly fail with the following error:
error: object expression of non-scalar type 'double [3][4]' cannot be used in a pseudo-destructor expression
Is it possible to build a lookup table this way in C++?
#include <unordered_map>
#include <vector>
namespace Mine{
template<class T>
using Matrix = std::vector<std::vector<T>>;
Matrix<double> AA = {
{5.04964676394959,-0.693207030363152,0.0422140829479668,-0.000968959310672217},
{2.6044054979329,0.288475262243944,-0.0208805589126506,0.000380899394040856},
{-4.32707864788065,1.07090008760872,-0.0777874445746693,0.00165150952598117}
};
static std::unordered_map<std::string, Matrix<double>* > parameter_store = { {"AA", &AA}};
}
#include <iostream>
int main()
{
std::cout << (*Mine::parameter_store["AA"])[0][0] << std::endl;
std::cout << (*Mine::parameter_store["AA"])[0][1] << std::endl;
std::cout << (*Mine::parameter_store["AA"])[1][2] << std::endl;
}
output
5.04965
-0.693207
-0.0208806
The Matrix<> template used here causes each row to store its length even though that's redundant. You can avoid this by used a std::array (but then you're locked into each matrix having equal dimensions since that's part of the type information) or using some library like Boost that provides a multidimensional array. That's an extremely small inefficiency though and unless you know you need to it might be best to not worry about that.
You can try wrapping double[3][4] in a structure/class
structure myMatrix {
double arr[3][4];
//if you want to initialize it
myMatrix(double[3][4] p){
//copy matrix here
}
};

Cast boost::any instance to its real type

I recently started to use Boost C++ library and I am testing the any class which can hold any data type. Actually I am trying to define the operator<< to print easily the content of any variable of type any (and sure, the class of the content should have the operator<< defined too).
I only started by sample types ( int, double ...) because they have be displayed by default. And till now, I have this code :
#include <boost/any.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;
ostream& operator<<(ostream& out, any& a){
if(a.type() == typeid(int))
out << any_cast<int>(a);
else if(a.type() == typeid(double))
out << any_cast<double>(a);
// else ...
// But what about other types/classes ?!
}
int main(){
any a = 5;
cout << a << endl;
}
So the problem here is that I have to enumerate all possible types. Is there any way to cast the variable to a particular type having the type_info of this particular type ?
Boost.Any any
With boost::any you cannot do that as others have already noted in comments. That is because boost::any forgets everything about the type of value it stores and requires you to know what type is there. While you have no way to enumerate every possible type.
The solution is to change boost::any so that it forgets everything about the type of value it stores except for how to stream it out. Mooing Duck provided one solution in comments. Another would be to write a new version of boost::any but extend its internals to support the streaming operation.
Boost.Spirit hold_any
Boost.Spirit already provides something like that in <boost/spirit/home/support/detail/hold_any.hpp>.
Boost.TypeErasure any
A far better approach is however to use Boost.TypeErasure's any as was mentioned by Kerrek SB in his comment.
An example for your case (use of <<) would look like this:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <iostream>
#include <string>
int main() {
typedef
boost::type_erasure::any<
boost::mpl::vector<
boost::type_erasure::destructible<>,
boost::type_erasure::ostreamable<>,
boost::type_erasure::relaxed
>
> my_any_type;
my_any_type my_any;
my_any = 5;
std::cout << my_any << std::endl;
my_any = 5.4;
std::cout << my_any << std::endl;
my_any = std::string("text");
std::cout << my_any << std::endl;
}

Another way to refer members in a structure

Now, I am learning as to how to use structures properly in C++.
Is there another way to refer members in a structure.
As an example, below is my code.
I want to know if I can do something like test.b to refer name member in the structure.
Is there any incredible way to do so?
#include <iostream>
using namespace std;
struct A
{
string name = "Test";
};
int main()
{
A test;
string b = "name";
cout << test.name;
return 0;
}
If you don't need to use a string to reference the member then the way to do this is called "pointer to member":
struct A
{
int name;
int value;
};
main()
{
int A::* b = &A::name; // assign "name" to the variable called b
struct A test = {1,2}; // make a structure and fill it in
return test.*b; // use the variable called b to reference test.name
}
If you do need to refennce the items with a string the other way mentioned in the contents is to use a map. That can be useful if all your members are the same type.
#include <iostream>
#include <map>
main()
{
std::map<std::string,int> test; // make something that can be keyed by a string
test["name"]=1; // put something called "name" in the map with a value of 1
test["value"]=2; // put something called "value" in the map with a value of 2
std::cout << test["name"] << std::endl;
return 0;
}
What you are referring to is called Reflection (function/attribute access by name). C++ by default doesn't have reflection. So probably you need to look for libraries/frameworks for that. Google "C++ Reflection" for that. Boost is one of the solution out there for C++ reflection/serialization.