【问题标题】:Boost function assignment throws exceptionBoost函数赋值抛出异常
【发布时间】:2012-08-31 20:03:10
【问题描述】:

当我尝试将一个函数 1 分配给另一个函数 1 时,Boost::function 十次中有一次向我抛出异常。

Task 是boost::function1<void, void*> 的类型定义。

具体代码如下:

    // the Task object sent in as Task task
    void Sleeper(void* arg)
    {
        int32_t sleepTime = *(int32_t*)arg;

        SleepCurrentThread((int32_t)sleepTime);
    }

    struct ThreadInfo
    {
        ThreadInfo() : mState(DETACHED), mTask(NULL), mArg(NULL)
        { }

        ThreadState mState;
        Task mTask;
        void* mArg;
    };

    Thread::Thread(Task task, void* arg, IMemoryAllocator& allocator, ILogManager& logger) : mAllocator(allocator), mLogger(logger)
    {
        mThreadInfo = (ThreadInfo*) mAllocator.Allocate(sizeof(ThreadInfo));  // simnple heap allocation

        mThreadInfo->mArg = arg;
        mThreadInfo->mState = Thread::RUNNING;
        mThreadInfo->mTask = task;     //<--------- throws... sometimes


        mHandle = _CreateThread(&Run, (void*)mThreadInfo);
        if (!mHandle)
            Detach();


    }

我在 boost function_template.hpp 中专门跟踪到了赋值运算符,在这段代码中,它最终抛出了:

// Assignment from another BOOST_FUNCTION_FUNCTION
    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
    {
      if (&f == this)
        return *this;

      this->clear();
      BOOST_TRY {
        this->assign_to_own(f);        // <--- throws, and then line below re-throws
      } BOOST_CATCH (...) {
        vtable = 0;
        BOOST_RETHROW;
      }
      BOOST_CATCH_END
      return *this;
    }

这是为什么?我的代码有什么容易发现的问题吗?还有什么需要的吗?

谢谢

编辑:我知道我会被要求使用 boost::threads,但我正在尝试我自己的 win32/pthread 包装器,(为了好玩)

【问题讨论】:

  • 尝试使用普通的旧new 而不是IMemoryAllocator 分配ThreadInfo,看看异常是否消失。
  • @ecatmur:不,是exception::what ;-P

标签: c++ boost boost-function


【解决方案1】:

您的struct 有一个重要的构造函数,但您没有调用它。它使Task 成员未初始化。要初始化它,要么使用new 分配整个对象,要么使用placement new 来初始化它,如下所示:

    void *mem = mAllocator.Allocate(sizeof(ThreadInfo));  // simnple heap allocation
    mThreadInfo = new(mem) ThreadInfo; // placement new

    mThreadInfo->mArg = arg;
    mThreadInfo->mState = Thread::RUNNING;
    mThreadInfo->mTask = task;

Placement new 在已分配的原始(未初始化)内存中构造一个对象。

【讨论】:

  • @KaiserJohaan:请注意,在解除分配之前,您还应该调用析构函数:mThreadInfo-&gt;~ThreadInfo()。上面的代码也不是异常安全的,即如果ThreadInfo构造函数抛出异常,那么你应该释放内存而不调用析构函数。
  • 所有这些都说明了低级的东西是多么困难,以及为什么你应该使用现有的高级库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-27
相关资源
最近更新 更多