什么原因导致删除大小不匹配?

时间:2016-07-31 18:33:39

标签: c++

为什么这段代码

#include <functional>
#include <iostream>
#include <memory>

struct Result {
  string value;
};

class BaseHandler {
 public:
  BaseHandler() {}
  void Handle() { std::cout << "Base Handler " << endl; }

  ~BaseHandler() {}
};

class Handler : public BaseHandler {
 public:
  Handler(const Result& result) : result_(result) {}
  void Handle() { std::cout << "Result: " << result_.value << endl; }

  ~Handler() {}

 private:
  Result result_;
};

class Dispatcher {
 public:
  void Dispatch() {
    std::unique_ptr<BaseHandler> handler = create_handler_();
    handler->Handle();
  }
  std::function<std::unique_ptr<BaseHandler>()> create_handler_;
};

void SetHandler(Dispatcher* dispatcher, Result some_result) {
  dispatcher->create_handler_ =
      [some_result]() -> std::unique_ptr<BaseHandler> {
    std::unique_ptr<BaseHandler> handler(new Handler(some_result));
    return handler;
  };
}

int main(int argc, char** argv) {
  Result some_result;
  some_result.value = "some_value";
  Dispatcher dispatcher;
  SetHandler(&dispatcher, some_result);

  dispatcher.Dispatch();
  return 0;
}

产生错误

F0731 11:28:05.092886   61642 debugallocation.cc:762] RAW: delete size mismatch: passed size 1 != true size 32
    @           0x49f053  (anonymous namespace)::RawLogVA()
    @           0x49ec05  base_raw_logging::RawLog()
    @           0x56d51b  tc_delete_sized
    @           0x40e65b  std::default_delete<>::operator()()
    @           0x40e513  std::unique_ptr<>::~unique_ptr()
    @           0x40da86  Dispatcher::Dispatch()
    @           0x40d527  main
    @     0x7f393a983ce8  __libc_start_main
    @           0x40cef9  _start
*** SIGABRT received by PID 61642 (TID 61642) from PID 61642; ***
Aborted (core dumped)

1 个答案:

答案 0 :(得分:3)

问题是BaseHandler和Handler的析构函数没有被声明为虚拟。

如果Handle在BaseHandler中被标记为虚拟并在Handler中重写,则编译器会生成关于析构函数未被声明为虚拟的错误。

以下代码按预期工作。

#include <functional>
#include <iostream>
#include <memory>

struct Result {
  string value;
};

class BaseHandler {
 public:
  BaseHandler() {}
  virtual void Handle() { std::cout << "Base Handler " << endl; }

  virtual ~BaseHandler() {}
};

class Handler : public BaseHandler {
 public:
  Handler(const Result& result) : result_(result) {}
  void Handle() override { std::cout << "Result: " << result_.value << endl; }

  virtual ~Handler() {}

 private:
  Result result_;
};

class Dispatcher {
 public:
  void Dispatch() {
    std::unique_ptr<BaseHandler> handler = create_handler_();
    handler->Handle();
  }
  std::function<std::unique_ptr<BaseHandler>()> create_handler_;
};

void SetHandler(Dispatcher* dispatcher, Result some_result) {
  dispatcher->create_handler_ =
      [some_result]() -> std::unique_ptr<BaseHandler> {
    std::unique_ptr<BaseHandler> handler(new Handler(some_result));
    return handler;
  };
}

int main(int argc, char** argv) {
  Result some_result;
  some_result.value = "some_value";
  Dispatcher dispatcher;
  SetHandler(&dispatcher, some_result);

  dispatcher.Dispatch();
  return 0;
}