Reputation: 38939
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
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 withint* 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 theDefaultConstructible
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