【问题标题】:Iterator tripping Visual C++ 2017 assertion迭代器触发 Visual C++ 2017 断言
【发布时间】:2018-09-23 03:45:28
【问题描述】:

我已将 Mark Borgerding 的 kissfft.hh(他的 FFT 代码的模板版本)复制到我的项目中,并将其修改为使用迭代器而不是指针。使用 Xcode 一切都很好。当我在使用 Microsoft 的 Visual C++ 2017 编译后尝试运行它时,我从以下代码中得到一个断言错误:

void transform(ComplexIterator fft_in, ComplexIterator fft_out) const
{
    ComplexIterator const Fout_beg = fft_out;
    ComplexIterator const Fout_end = fft_out + p*m;

    do{
        *fft_out = *fft_in;
        fft_in += fstride;
    }while(++fft_out != Fout_end );
    ...

ComplexIterator 是一个模板类型,在这种情况下它是一个普通的std::vector< std::complex<float> >::iterator。有时Fout_end 指向std::vector 中间的某个位置,有时它指向std::vector 中最后一个元素之后的一个点,就像std::vector.end()。当它指向最后一个元素之后的一个点时,while 语句会导致断言错误,因为迭代器经过了向量中的最后一个元素。它只过去了一个(即它等于Fout_end),但这并不重要。

问题是,我认为这是迭代器的标准做法。你不断迭代直到你点击“结束”,它在std::vector之外。我创建了一个简单的测试程序来检查它是否也触发了断言检查。

std::vector<int> p(5);
for (auto it = p.begin(); it != p.end(); ++it) {
    std::cout << *it << std::endl;
}

它没有。这里发生了什么?为什么 FFT 代码会触发断言检查?我可以通过切换到发布模式来解决问题,然后一切正常,但我想知道我是否做错了什么。

【问题讨论】:

  • 您确定断言来自 fft_out 而不是来自 fft_in?你能生成一个minimal reproducible example吗?
  • @n.m.嗯,我很确定它发生在“while”行,但也许你是对的。我现在做不到,但我明天会检查。
  • 如果fft_out 指向一个空向量,您的代码将取消对end() 的引用。
  • @IgorTandetnik 是的,但向量不为空。
  • 发布完整的断言错误。

标签: c++ visual-studio c++11 stl visual-studio-2017


【解决方案1】:

原来@n.m.完全正确-问题是 fft_in 而不是 fft_out ,就像我想的那样。我展开了do...while 循环的最后一次迭代以避免该问题而不会产生性能成本(我认为)。

 ComplexIterator const Fout_beg = fft_out;
 ComplexIterator const Fout_end = fft_out + p*m;

 ComplexIterator const Fout_almost_end = Fout_end - 1;
 do{
     *fft_out = *fft_in;
     fft_in += fstride;
 }while (++fft_out != Fout_almost_end);
 *fft_out = *fft_in;

【讨论】:

    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多