【问题标题】:Visual Studio const_iterator Assignment ErrorVisual Studio const_iterator 赋值错误
【发布时间】:2015-12-21 07:40:45
【问题描述】:

在 Visual Studio 2010 上分配默认构造的 vector<int*>::const_iterator 错误。我已经在 5 个都具有 Service Pack 1 的 Visual Studio 2010 系统上进行了尝试。它在 3/5 机器上失败,我已经能够确定导致 3 个系统故障的原因,但我似乎找不到错误报告。

代码如下:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int*> vec;
    int arr[3] = {};

    for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) vec.push_back(arr + i);

    vector<int*>::const_iterator initialized = vec.cbegin();
    vector<int*>::const_iterator uninitialized;

    initialized = uninitialized;

    cout << "Hello World" << endl;

    return 0;
}

很明显,除了 cout &lt;&lt; "Hello World" &lt;&lt; endl; 之外的所有内容都在 Release 中进行了优化,因此这个最小的示例只会在 Debug 中失败。但在 Debug 中,它给出的错误是:

test.exe 中 0x01071e14 处未处理的异常:0xC0000005:访问冲突读取位置 0x00000000。

比较链接的工作和非工作 MSVCP100D.dll 显示存在细微差异,工作 .dll 是产品版本:10.0.40219.325,非工作 .dll 是产品版本:10.0.40219.1。

实际错误发生在

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xutility

再次区分工作和非工作版本表明对工作版本进行了更改。不工作的代码只是说:

if (_Myproxu != _Right._Myproxy)
    _Adopt(_Right._Myproxy->_Mycont);

工作代码说:

if (_Myproxy == _Right._Myproxy)
    ;
else if (_Right._Myproxy != 0)
    _Adopt(_Right._Myproxy->_Mycont);
else
    {   // becoming invalid, disown current parent
    _Lockit _Lock(_LOCK_DEBUG);
    _Orphan_me();
    }

说了这么多,这是我的实际问题。如何获取此更新?我已使用 Windows Update 更新到最新版本,但问题仍未解决。是否有一些我需要去某个地方才能获得的隐藏补丁?我在任何地方都找不到这个问题,所以我也找不到有关补丁的信息。

【问题讨论】:

  • @JamesAdkison,你显然做到了。 HAVING unititialized iterator 没有错,只要它没有被取消引用。至于为什么,很容易看出当迭代器是某些对象的成员时会发生这种情况,并且将一个对象(以某种方式初始化)分配给另一个对象,而事实并非如此。
  • @JamesAdkison,我不是 OP,所以我不确定他想做什么。但是,从表面上看(我无法验证),提供的代码不应该使程序崩溃。如果是这样,这是一个糟糕的实现错误。我试图看看这在现实生活中何时会发生,因为显然发布的代码是示范性的。而且我不确定您所说的“混合”是什么意思。当然,您不应该比较那些迭代器。但是将它们分配给彼此并没有错。
  • 我很确定这在技术上是 UB。 uninitialized 是奇异值,[iterator.requirements.general]/p6 明确指出“大多数表达式的结果对于奇异值是未定义的;唯一的例外是销毁包含奇异值的迭代器,分配非奇异值值到持有奇异值的迭代器,并且对于满足DefaultConstructible 要求的迭代器,使用值初始化的迭代器作为复制或移动操作的源。"
  • @JonathanMee 奇异值是不与任何序列相关联的值。例如,空指针或未初始化的指针。

标签: c++ visual-studio visual-studio-2010 iterator initialization


【解决方案1】:

此代码具有未定义的行为。 [iterator.requirements.general]/p6:

迭代器也可以有不相关的奇异值 任何序列。 [例子:声明一个未初始化的之后 指针x(与int* x; 一样),x 必须始终假定具有 指针的奇异值。 —结束示例 ] 大多数的结果 对于奇异值,表达式未定义;唯一的例外是 销毁持有奇异值的迭代器,分配 持有奇异值的迭代器的非奇异值,并且, 对于满足DefaultConstructible 要求的迭代器, 使用值初始化的迭代器作为复制或移动的源 手术。 [ 注意:默认情况下不提供此保证 初始化,尽管区别只对具有 微不足道的默认构造函数,例如持有的指针或聚合 指针。 —尾注] 在这些情况下,奇异值是 以与任何其他值相同的方式覆盖。可取消引用的值 总是非单数的。

uninitialized 是单数,它的使用不属于段落中列出的任何例外。

但是,鉴于您发布的 sn-ps,我怀疑即使您对 uninitialized 进行值初始化,您的代码也无法工作,这是 Microsoft 实现中的一个错误,他们在 later hotfix 中修复了该错误.

【讨论】:

猜你喜欢
  • 2021-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-18
  • 2017-09-06
  • 2014-01-13
  • 2018-04-27
相关资源
最近更新 更多