STL list::remove does not remove all the occurrences of an element from the list in a debug build in Visual C++ (250848)



The information in this article applies to:

  • Microsoft Visual C++, 32-bit Enterprise Edition 6.0
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET (2003)
  • Microsoft Visual C++ .NET (2002)

This article was previously published under Q250848
Note Microsoft Visual C++ .NET 2002 and Microsoft Visual C++ .NET 2003 support both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model. The information in this article applies only to unmanaged Visual C++ code. Microsoft Visual C++ 2005 supports both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model.

SYMPTOMS

The Standard Template Library (STL) list::remove function does not remove all the occurrences of an element from the List in a Debug build when an iterator is passed as a parameter. However, in a Release build, list::remove does remove all the occurrences of an element from the List. Sometimes (with multiprocess computers), remove does not erase all occurrences in both Debug and Release builds.

CAUSE

The STL list::remove function is defined as taking a "const T &" argument. Passing an iterator means passing the reference to the element that is pointed to by the iterator. After the first occurrence of the element is removed, list::remove invalidates the iterator address so that the next occurrence of the element is not removed in a Debug build.

In a Release build, after the first occurrence of the element is removed, the reference to the iterator address is still valid, so all the occurrences of the element are removed.

RESOLUTION

Instead of passing the reference of the element to list::remove, pass the actual value of the element.

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce Behavior

The following example code demonstrates this problem:
#include <list>
#include <iostream>
using namespace std;

typedef list <int> MY_LIST_OF_INT;

int main()
{
            int elem[6] = {2,1,2,3,2,2}, element;
	
   	MY_LIST_OF_INT		MyList;
   	MY_LIST_OF_INT::iterator	it_begin, it_temp;
   	
   	for(int x = 0; x < 6; x++)
		MyList.push_back(elem[x]);
	
   	cout << "Elements in List before Remove" << endl;
   	for(it_begin = MyList.begin(); it_begin != MyList.end(); ++it_begin)
		cout << *it_begin << " ";
   	cout << endl;

	it_temp = MyList.begin();
	MyList.remove(*it_temp);

   	cout << "Elements in List after Remove " << endl;
   	for(it_begin = MyList.begin(); it_begin != MyList.end(); it_begin++)
		cout << *it_begin << " ";
   	cout << endl;
   	return 1;
}

				

Modification Type:MajorLast Reviewed:1/11/2006
Keywords:kbtshoot kbLangCPP kbprb kbSTL kbtemplate KB250848 kbAudDeveloper