boost :: shared_ptr dereference中boost :: filesystem3 :: detail :: dir_itr_imp的含义

时间:2016-08-26 17:14:58

标签: c++ boost

我使用以下代码列出目录:

for ( const auto& fileEntry : boost::make_iterator_range( boost::filesystem::directory_iterator( some_directory ), {} ) )
{
    const boost::filesystem::path tmpFullName = fileEntry.path();

    if ( boost::filesystem::exists( tmpFullName ) &&
        boost::filesystem::is_regular_file( tmpFullName ) &&
        (boost::filesystem::extension( tmpFullName ) == ".doc") )
    {
        processFile( tmpFullName.string() );
    }
}

我偶尔看到以下错误

  

/boost/1.47.0/include/boost-1_47/boost/smart_ptr/shared_ptr.hpp:420:   T * boost :: shared_ptr :: operator->()const [with T =   boost :: filesystem3 :: detail :: dir_itr_imp]:断言`px!= 0'失败。

在我的代码中,我没有定义任何boost shared_ptr而是我只使用std :: unique_ptr。 因此,我认为潜在的问题在于上面的列表函数。

有人可以仔细检查这个功能,看看这里是否有潜在的问题?

4 个答案:

答案 0 :(得分:1)

函数directory_iterator_increment()(在operations.cpp中)包含以下代码:

1940: if (temp_ec)
1941: {
1942:   it.m_imp.reset();
1943:   if (ec == 0)
1944:     BOOST_FILESYSTEM_THROW(
1945:       filesystem_error("boost::filesystem::directory_iterator::operator++",
1946:         it.m_imp->dir_entry.path().parent_path(),
1947:         error_code(BOOST_ERRNO, system_category())));
1948:   ec->assign(BOOST_ERRNO, system_category());
1949:   return;
1950: }

第1946行在第1942行重置后解除引用it.m_imp。这会导致观察到的行为。

编辑添加:

这在以后的版本中得到修复:https://svn.boost.org/trac/boost/ticket/5900

答案 1 :(得分:0)

您使用的是什么编译器?它可能是您正在使用的c ++库版本与boost的不匹配。

答案 2 :(得分:0)

Boost在目录迭代器内部使用shared_ptr,因为" shared_ptr提供了InputIterators所需的浅拷贝语义," (boost / filesystem / operations.hpp,第924行,来自Boost v1.61)。在v1.61中,对于解除引用end迭代器的情况有一个显式断言,但是v1.47可能仅仅依赖于shared_ptr解除引用的断言。

我的猜测是迭代器在某处无效。在这些情况下目录不存在的任何可能性?也许从另一个线程/进程发生对目录的更改?

BTW,v1.61包含begin() / end()函数,用于在基于范围的for循环中启用directory_iterator。也许它不是在v1.47中,但如果是,我依靠它而不是明确地使用make_iterator_range()

答案 3 :(得分:0)

您确定第一行中的{}是否正在生成您期望的结束迭代器?

尝试明确构建它,看看它是否有所作为:

boost::make_iterator_range(
    boost::filesystem::directory_iterator( some_directory ),
    boost::filesystem::directory_iterator()  // instead of '{}'
)