A problem with vectors

Here's the situation: I have a static vector of HWND's. When a window is created it's handle is appended to the end of the vector. When a window is destroyed its HWND is removed from the vector. It's supposed to, that is. I've tested the process by implementing several instances of the class, thus creating the windows for each. The while loop in the WM_DESTROY message correctly identifies which HWND in the vector is the HWND of the destroyed window. If I destroy the first window i is equal to 0, 1 for the second, etc... The window is destroyed just fine, but when I go to erase the item out of the vector using _MyTypeWindowList.erase(_MyTypeWindowList.begin()+i); I get an error. Any insight as to why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
static vector <HWND> _MyTypeWindowList;

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
{
	switch(wm)
	{
	case WM_CLOSE:
		{
			DestroyWindow(hwnd);
		}
	case WM_DESTROY:
		{
			int i = 0;
			while(i < _MyTypeWindowList.size())
			{
				if(hwnd == _MyTypeWindowList[i])
				{
					break;
				}
				i++;
			}
			
			_MyTypeWindowList.erase(_MyTypeWindowList.begin()+i);
			if(GetMyTypeWindowListSize() == 0)
			{
				PostQuitMessage(0);
			}
			return 0;
		}
	default:
		break;
	}
	return DefWindowProc(hwnd, wm, wParam, lParam);
}
void SetHWnd(HINSTANCE hInstance)
{
	_hWnd = CreateWindowEx(
		NULL,
		GetSzClassName(),
		GetSzWindowName(),
		WS_OVERLAPPEDWINDOW,
		0,0,
		500,500,
		NULL,
		NULL,
		hInstance,
		NULL);
		AppendMyTypeWindowListItem(_hWnd);
}
void AppendMyTypeWindowListItem(HWND hWnd)
{
	_MyTypeWindowList.push_back(hWnd);
}




Last edited on
You are blindly erasing an item. By the time you call for erase(), you don't know why you left the immediately-above loop. Did you exit the loop because you found a matching window handle, or did you exit the loop because there was no match? You need to call erase() only if you exited the loop because you found a match.

The easiest would be to call for erase() inside the while loop, just before breaking.
Thanks for the good advise. I will do that. However, thoroughly debugged the code, the value of i is exactly what I expected it to be. If there are two values in vector, shouldn't vector.begin() + 0 erase the first one or vector.begin() + 1 erase the second?
It should work. What's the error that you get? Also note that std::vector provides a find() function.
Well, moving the erase() function immediately before the break solved the problem. An explaination of why would be greatly appreciated.
Degbug Assertion Failed!
Expression: vector erase iterator outside range.
Meaning the iterator was out of range. Sounds to me that your vector is empty.
except that the size() function returned 2 before the erase().
The only thing I did differently was move the erase() into the if statement before the break.
The variable f is assigned the value 2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
		case WM_DESTROY:
			{
				int i = 0;
				while(i < _MyTypeWindowList.size())
				{
					if(hwnd == _MyTypeWindowList[i])
					{
						
						break;
					}
					i++;
				}
				int f = _MyTypeWindowList.size();
				_MyTypeWindowList.erase(_MyTypeWindowList.begin()+i);
				if(GetMyTypeWindowListSize() == 0)
				{
					PostQuitMessage(0);
				}
				return 0;
			}
		default:
			break;
		}
		return DefWindowProc(hwnd, wm, wParam, lParam);
	}
Last edited on
Topic archived. No new replies allowed.