mercredi 27 mars 2019

Unable to dereference pointer

I am writing an implementation of the Haskell Maybe Monad in C++11.

However I got stuck when I tried to test the code. When I construt a value of the type with the pseudo constructor Just and then try to evaluate it with using the function fromJust (that should just "unpack" the value placed inside the Maybe) the program stops and eventually terminates silently.

So i tried to debug it; here is the output for the code of testMaybe.cpp:

c1
yeih2
value not null: 0xf16e70

I added a couple of print statements to evaluate where the program stops, and it seems to stop at the exact point where I dereference the pointer to return the value. (I have marked it in the code.)

At first I thought that the value in the maybe might have been deconstructed by the time i want to dereference the pointer, which, to my understanding, would result in undefined behaviour or termination. However, I was unable to find the place where that would have happened.

Can you please give me a hint on why this is happening?

testMaybe.cpp:

#include<iostream>
#include "Maybe.hpp"
using namespace std;
using namespace Functional_Maybe;
int main() {
        Maybe<string> a{Maybe<string>::Just("hello") };
        if(!isNothing(a)) cout << "yeih2 " << fromJust(a) << endl;
        return 0;
}

Maybe.hpp

#pragma once
#include<stdexcept>
#include<iostream>
using namespace std;
namespace Functional_Maybe {

  template <typename T>
  class Maybe {
    const T* value;

    public:
          Maybe(T *v) : value { v } {}            //public for return in join
          const static Maybe<T> nothing;

          static Maybe<T> Just (const T &v) { cout << "c1" << endl; return Maybe<T> { new T(v) }; }

          T fromJust() const {
                  if (isNothing()) throw std::runtime_error("Tried to extract value from Nothing");
                  cout << "\nvalue not null: " << value << " " << *value << endl;
                                        //                        ^ stops here
                  return *value;
          }

          bool isNothing() const { return value==nullptr; }

          ~Maybe() { if (value != nullptr) delete value; }
  };

  template <typename T>
  bool isNothing(Maybe<T> val) {
    return val.isNothing();
  }

  template <typename T>
  T fromJust(Maybe<T> val) {
    return val.fromJust();
  }
}

Aucun commentaire:

Enregistrer un commentaire