std::future<neither::Either<int, std::string>> segmentation fault

David Freitag

The code in this question uses the Either<> implementation found here: https://github.com/LoopPerfect/neither. To be clear, I doubt that this is a problem with this specific library, otherwise I would have created an issue there.

The following snippet works as expected:

std::future<std::string> f = std::async(std::launch::async, []()
{
    return "test";
}

std::cout << f.get() << std::endl;

And the following generates a segmentation fault:

std::future<neither::Either<int, std::string>> f = std::async(std::launch::async, []()
{
    return neither::Either<int, std::string>(neither::right(std::string("test")));
});

neither::Either<int, std::string> v = f.get(); // Segmentation fault
std::cout << v.right().value << std::endl;

Returning left(-1) works, as does neither::Either<int, int> for both left() and right(). I know that std::future::get might generate a segfault is that you've called it twice, in which case std::future::valid will return false just prior to calling get, but valid returns true.

Is there something I'm missing here?

Barry

Is there something I'm missing here?

The library isn't properly implemented. Specifically for the purposes of this question, the copy constructor is wrong:

constexpr Either( Either<L, R> const& e )
  : isLeft(e.isLeft) {
  if(isLeft) {
    leftValue = e.leftValue;
  } else {
    rightValue = e.rightValue; // (*)
  }
}

We can't assign to this->rightValue there, there isn't a std::string in existence at that spot - we have uninitialized memory.

A correct copy constructor would be:

Either(Either<L, R> const& e)
  : isLeft(e.isLeft)
{
  if(isLeft) {
    new (&leftValue) L(e.leftValue);
  } else {
    new (&rightValue) R(e.rightValue);
  }
}

or, since we're writing generic library code that could be used by all sorts of evil types, you'll want:

::new (static_cast<void*>(std::addressof(leftValue))) L(e.leftValue);

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Segmentation fault with std::uniform_int_distribution

Segmentation fault assigning std::string in a struct

Segmentation fault when using std::string

Segmentation fault in std::transform

insert(std::map<int,struct>) segmentation fault (core dumped)

Segmentation fault in std::vector destructor

std::vector Sprite segmentation fault

Segmentation fault with const string& constructor and templated std::set find

shared memory of std::string give segmentation fault (linux)

Declaring a std::string after Unicode to ASCII conversion is giving Segmentation fault

"Segmentation Fault" while using std::list.back() on a non-empty std::list<int>

-fshort-wchar and std::wstring - segmentation fault

Segmentation fault with std::function and lambda parameters

C++11 Segmentation fault with std::promise

Segmentation fault when initializing a std::vector<double>

Segmentation fault when storing lambda as std::function

Segmentation fault when removing from std::vector

C++ Segmentation fault at std::map::insert

template class with std string argument gives segmentation fault when using local array as storage

Weird SIGSEGV segmentation fault in std::string::assign() method from libstdc++.so.6

reinterpret_cast<std::string*> cause segmentation fault on gcc but works on clang

Getting unknown Segmentation Fault "(address) in std::__cxx11::basic_string<char, std::char_traits<char>,..., std::allocator<char> > const&) const ()

Converting an int to std::string

Append int to std::string

Why does this std::function and operator cause a segmentation fault?

Segmentation fault when erasing elements while iterating std::deque

using remove method of std::list in a loop is creating segmentation fault

std::iterator segmentation fault when using it as a class variable

Segmentation fault when trying to push_back to a std::vector