Jonathan Mee
Jonathan Mee

Reputation: 38939

Visual Studio const_iterator Assignment Error

The assignment of a default constructed vector<int*>::const_iterator errors on Visual Studio 2010. I've tried this on 5 Visual Studio 2010 systems that all have Service Pack 1. It fails on 3/5 machines, I've been able to identify what is causing the failure on the 3 systems but I cannot seem to find a bug report.

Here is the code:

#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;
}

Clearly everything but the cout << "Hello World" << endl; is optimized out in Release so this minimal example will only fail in Debug. But in Debug the error it gives is:

Unhandled exception at 0x01071e14 in test.exe: 0xC0000005: Access violation reading location 0x00000000.

Comparing the working and non-working MSVCP100D.dlls that were linked shows that there is a slight discrepancy, the working .dll is Product Version: 10.0.40219.325 and the non-working .dll is Product Version: 10.0.40219.1.

The actual error occurs in

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

And again diffing the working and non-working version shows that a change has been made to the working version. The non-working code simply says:

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

The working code says:

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();
    }

All that to say, here's my actual question. How do I get this update? I've updated to the latest using Windows Update, but the problem has not been resolved. Is there some hidden patch that I need to go somewhere to get? I can't find this issue written up anywhere, so I also can't find information about the patch.

Upvotes: 2

Views: 435

Answers (1)

T.C.
T.C.

Reputation: 137425

This code has undefined behavior. [iterator.requirements.general]/p6:

Iterators can also have singular values that are not associated with any sequence. [ Example: After the declaration of an uninitialized pointer x (as with int* x;), x must always be assumed to have a singular value of a pointer. —end example ] Results of most expressions are undefined for singular values; the only exceptions are destroying an iterator that holds a singular value, the assignment of a non-singular value to an iterator that holds a singular value, and, for iterators that satisfy the DefaultConstructible requirements, using a value-initialized iterator as the source of a copy or move operation. [ Note: This guarantee is not offered for default initialization, although the distinction only matters for types with trivial default constructors such as pointers or aggregates holding pointers. —end note ] In these cases the singular value is overwritten the same way as any other value. Dereferenceable values are always non-singular.

uninitialized is singular, and its use doesn't fall within any of the exceptions listed in the paragraph.

However, given the snippets you post, I suspect that your code wouldn't work either even if you value-initialize uninitialized, which is a bug in Microsoft's implementation, and which they fixed in a later hotfix.

Upvotes: 1

Related Questions