Monday, March 26, 2012

Visual Studio 2010 C++ set iterator issue | Set data structure in VS2010 - Part I


You may have come across some issues with Visual Studio 2010 when  you use the set data structure in your C++ program. If you want to compile the existing codes with VS 2010 IDE it may not be compiled as you expected. Here i am going to address one of those issues & the way to sort out the problem in some extent.


Let we start with simple shit of coding, then in our next post we can further look into complex problems using user defined class.

main1.cpp

#include <cstdlib>
#include <iostream>
#include <set>


using namespace std;
int main()

set<int> setInt;


for(int i=0; i<5; ++i)
setInt.insert(i);

for(set<int>::iterator iItr=setInt.begin(); iItr!=setInt.end(); iItr++)
{
*iItr = 10;
}

system("pause");
return 0;
}



If you compile the above code in VS 2010 it would give the error message like this. [error C3892: 'iItr' : you cannot assign to a variable that is const] The reason for this, in VS2010 set iterators will be considered as const iterator though you use normal ::iterator or ::const_iterator. It doesn't matter what is the iterator type you use, at the end all will be fallen under the category of const. The elements in the set are treated as constant. you can not change the elements property using set::iterator. Actually this was possible in the Visual Studio 2008 & earlier versions.

The reason for this error is, in the set data structure elements are sorted in a particular order and allowed to have unique entries. So if we change the element's properties in the set, the ordering will get affected. All elements needs to re arranged. Therefore, it's a acceptable reason for having the iterators as const iterator. This const iterators simply don't allow us to change the elements in the container. (Obviously that is the const iterators role). 

Then You can ask, what is the hell of not enabling this feature in Visual Studio 2008 & earlier versions? What to do with it. Yes it is their mistake, it should have been done before that. But theoretically this standard came after the VS 2008. So we can not blame even Microsoft as well.

main2.cpp


#include <cstdlib>
#include <iostream>
#include <set>

using namespace std;
int main()
{
set<int> setInt;

for(int i=0; i<5; ++i)
 setInt.insert(i);


for(set<int>::iterator iItr=setInt.begin(); iItr!=setInt.end(); iItr++)
{
if((*iItr) == 2)
setInt.erase(iItr);
}
system("pause");
return 0;
}


If you compile this code segment it won't be giving errors in compiling but rather must give the crashing issue at the run time. Since you removed one element from the set container's order got affetcted , just after the erasing that iterator iItr is no longer valid for accessing the elements. It would link with the arbitrary location and finally give unhandled exception : Access violation run time error

Next post we will see the tricks to overcome this issue.

For Incoming searches
- error C3892:  you cannot assign to a variable that is const
- VS 2010 compilation errors
- Visual Studio 2010 Set run time crashing
- VS 2010 set data structure convention change