I'm transitioning my old, dinasour-ish program written with arrays and pointers to vectors and ran into some problem with iterators. I'm using Visual Studio 2005 SP1.

In debug mode the follow message appeared upon reaching the part of the code indicated further below:
Debug Assertion Failed!

expression ("_Myptr > ((_Myvec*)(this->_Mycont))->_Myfirst",0)

I clicked "retry" and was led to vector.h to the following part of this header file:

_Myt& operator--()
		{	// predecrement
		_SCL_SECURE_VALIDATE(this->_Mycont != NULL);
		_SCL_SECURE_VALIDATE_RANGE(_Myptr > ((_Myvec *)(this->_Mycont))->_Myfirst);
		--_Myptr;
		return (*this);
		}

My program is pasted below:

void quicksort2(vector<A*>::iterator begin,vector<A*>::iterator end)//sorting program adapted from the famous recursive quicksort method,A is a struct, Wto is a float type member of this struct. the input argument for quicksort2 is simply the range of the vector elements to be sorted.
{
	A *temp;
	vector<A*>::iterator i=begin,j=end;
	
	double pivot=(*(begin+(end-begin)/2))->Wto;
	//partitioning starts;
	while(i<=j)
	{
		while((*i)->Wto>pivot)
			i++;
		while((*j)->Wto<pivot)
			j--;
		if(i<=j)
		{
			temp=*i;
			*i=*j;
			*j=temp;
			i++;j--;
		}
	}
//the recursive part
	if(begin<j)
		quicksort2(begin,j);//The error usually occurs here, depending on the input.
	if(i<end)
		quicksort2(i,end);
}

void test1()//test harness for the functionality of vectors and the modified quicksort algorithm
{
	ifstream in;int i;
	in.open("test2.txt");

	A *ND;
	ND=new A[100];

	for(i=0;i<100;i++)
		in>>ND[i].Wto>>ND[i].Range;

	//***********shuffle ND************
		
	random_shuffle(ND,ND+100);
	
	for(i=0;i<100;i++)
		cout<<ND[i].Wto<<" "<<ND[i].Range<<endl;

cout<<endl<<endl;
	//**********************************

	vector<A*> old;
	

	for(i=0;i<100;i++)
	old.push_back(ND+i);

	vector<A*>::iterator iter=old.begin();
	vector<A*>::iterator iter2=old.end()-1;
	vector<A*>::iterator iter3=old.begin()+old.size()-1;
	//******************quicksort***********
	quicksort2(iter,iter2);//this line actually runs okay
	
	quicksort2(old.begin(),old.end()-1);//the second time quicksort2 is called the error mentioned above occurred. 
	

}

int main()// my actual main() function contains more stuff but only test1() is being tested. test1(); comes at the very beginning of main() so the remaining part of the program shouldn't have led to this error
{
test1();

return 0;
}

What makes me feel wierd is that if quicksort2 is called only once then no crash occurs. It can be called using iter and iter2 or iter3 or old.begin() and old.end() without any problem but once quicksort2 has been run once then all subsequent calls to this function result in crashes of the same kind.

I read the part about iterators and containers in C++ Primer back and forth twice but still haven't got a clue what's wrong with my use of iterators. The book says iterators can be invalidated if the size of the vector is changed but in my case no re-sizing whatsoever is done in quicksort, only the elements of vector old have been sorted. Even if iter and iter2 are rendered invalid after the first pass, why are old.begin() and old.end() also causing a crash(see code above)? I'v also tried redefining iter and iter2 to old.begin() and old.end()-1 then pass them into quicksort2 but a crash still occurred....

By the way I'm surprised to find Visual Studio's Watch unable to display the values of expressions such as *iter or (*iter)->Wto. Can this be related to my possible misuse of iterators?

Recommended Answers

All 3 Replies

Lin 6 fills me with some dread. What do you suppose (end-begin) does?

When end and begin where pointers in your array/pointer implementation the answer was obvious but now end and begin are not pointers, they are objects and I am slightly surprised that that construction even compiles as I would not really expect operator- to be implemented for an iterator.

Line 23 and 25 fill me with similar dread but there is some evidence that random access iterators support operator< so it may be OK.

Actually my C++ references seem to be very short on what methods any iterator actually implements and I think it is this (and other similar omissions) that leave me quite dissatisfied with a lot of C++ documentation.

Lin 6 fills me with some dread. What do you suppose (end-begin) does?

When end and begin where pointers in your array/pointer implementation the answer was obvious but now end and begin are not pointers, they are objects and I am slightly surprised that that construction even compiles as I would not really expect operator- to be implemented for an iterator.

Line 23 and 25 fill me with similar dread but there is some evidence that random access iterators support operator< so it may be OK.

Actually my C++ references seem to be very short on what methods any iterator actually implements and I think it is this (and other similar omissions) that leave me quite dissatisfied with a lot of C++ documentation.

Thanks. I'm totally new to vectors and what you saw were mostly adaptations from my original code. The (end-begin) line was written to see if it is the second argument that passed to quicksort2 that caused the problem. I tried numerous combinations of different iterators(iter,iter2, iter3) but the crash pattern is the same: subsequent call to quicksort2 always leads to this error.

Comparisons such as if(begin<j) were vestiges of the previous code. I often confuse iterators with pointers but I don't really see how this could have caused any problem? If it is, what is the proper way of writting such if statements using iterators? if(begin!=j) maybe?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.