迭代器触发 Visual C++ 2017 断言

Posted

技术标签:

【中文标题】迭代器触发 Visual C++ 2017 断言【英文标题】:Iterator tripping Visual C++ 2017 assertion 【发布时间】: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 是的,但向量不为空。 发布完整的断言错误。 【参考方案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;

【讨论】:

以上是关于迭代器触发 Visual C++ 2017 断言的主要内容,如果未能解决你的问题,请参考以下文章

c++ 断言字符串迭代器偏移超出范围

SWIG 在 Windows 中生成 C++ Python3 包装器导致断言 MSVC 2017

C++ Visual Studio:调试断言失败!表达式:c >= -1 && c <= 255

为啥在Visual Studio中擦除位置之前矢量的c ++迭代器也无效?

在 Visual C++ 2005 中开发的 Visual C++ 项目 - 在 Visual C++ 2010 中,打开菜单时调试断言失败,但发布模式有效,如何解决?

iterator_traits实现