无法取消引用指针

问题描述 投票:2回答:1

我正在编写C ++ 11中的Haskell Maybe Monad的实现。

但是当我尝试测试代码时,我遇到了困难。当我使用伪构造函数Just构造类型的值然后尝试使用函数fromJust(它应该只是“解包”置于Maybe中的值)来评估它时,程序停止并最终以静默方式终止。

所以我试着调试它;这是testMaybe.cpp代码的输出:

c1
yeih2
value not null: 0xf16e70

我添加了几个print语句来评估程序停止的位置,它似乎停在我取消引用指针以返回值的确切位置。 (我在代码中标记了它。)

起初我认为可能在我想要取消引用指针的时候解构了这个中的值,根据我的理解,这将导致未定义的行为或终止。但是,我无法找到发生这种情况的地方。

你能否告诉我为什么会这样?

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();
  }
}
c++ c++11 pointers dereference
1个回答
4
投票

你的类模板Maybe拥有资源(动态分配的T),但不遵循Rule of Three:(隐式定义的)复制和移动操作仅执行浅拷贝,这导致使用后免费和双重免费问题。您应该为您的类实现正确的复制和移动操作(cosntructors和赋值运算符),或者使用std::unique_ptr<const T>作为value的类型,并删除您的手动析构函数(从而遵循首选的Zero规则)。

旁注:你有没有看过std::optional(或者,在前C ++ 17版本中,boost::optional)?他们似乎正在为你提议的课做一些非常相似(甚至完全相同)的事情,你可能想要使用它们(或者如果你更适合你,可以在课堂内部使用它们)。它们甚至可能更高效,在某些情况下使用小对象优化来避免动态内存分配。

© www.soinside.com 2019 - 2024. All rights reserved.