Visual C++ "Access violation accessing location..."

I have these two functions listed below. DoEvent() gets called from a window procedure whenever some event occurs. SetEvent() sets an element of the m_Events array a pointer to a Command object to handle the event. The array is zeroed in the constructor.

The error occurs on line 16 in the code in DoEvent(). It's bugging me out because I have absolutely no idea why the array is suddenly unreadable. When I call SetEvent() it works just fine, no problem.

When I step through the debugger in SetEvent i see that each element begins as 0 and the element I set is set properly. However, when I step through DoEvent() all elements in m_Events show "?????" "Unable to read memory".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uw::Command* uw::WindowBase::SetEvent(uw::WindowEventsEnum event, uw::Command* command)
{
	if (event < 0 || event >= FINAL_EVENT_ENTRY)
		return NULL;

	Command* ret = m_Events[event];
	m_Events[event] = command;
	return ret;
}

BOOL uw::WindowBase::DoEvent(uw::WindowEventsEnum event, LPVOID pdata)
{
	if (event < 0 || event >= FINAL_EVENT_ENTRY)
		return FALSE;

	if (!m_Events[event])
		return FALSE;

	return m_Events[event]->Do(pdata);
}


Here is the definition of WindowBase:
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
class WindowBase
{
public:
	WindowBase();
	virtual ~WindowBase();

	BOOL Create(LPCWSTR caption, LPCWSTR wndclass, DWORD styles, DWORD exstyles = 0, HWND parent = NULL);
	
	Command* SetEvent(WindowEventsEnum event, Command* command);
	BOOL DoEvent(WindowEventsEnum event, LPVOID pdata);

protected:
	HWND m_Window;
	HWND m_Parent;
	HDC m_WindowDC;
	RECT m_WindowRect;
	RECT m_ClientRect;

	Command* m_Events[FINAL_EVENT_ENTRY];

	WNDPROC m_DefProc;

	static LRESULT CALLBACK s_SubProc(HWND, UINT, WPARAM, LPARAM);

};


Please let me know if you need more info.
Last edited on
For the record here's the WindowEventsEnum enum and the Command class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum WindowEventsEnum {
	EVENT_ONDESTROY,		// X
	EVENT_ONERASE,			// X
	EVENT_ONPAINT,			// X
	EVENT_ONMOVE,			// X
	EVENT_ONSIZE,			// X
	EVENT_ONMOUSEPRESS,		// X
	EVENT_ONMOUSERELEASE,	// X
	EVENT_ONMOUSEMOVE,		// X
	EVENT_ONMOUSEWHEEL,		// X
	EVENT_ONKEYPRESS,		// X
	EVENT_ONKEYRELEASE,		// X
	EVENT_ONKEYCHAR,		// X

	FINAL_EVENT_ENTRY
};

1
2
3
4
5
6
7
8
9
class Command
{
public:
	virtual ~Command() {}

	virtual BOOL Do(LPVOID pdata) = 0;
	virtual BOOL Undo() { return FALSE; }

};


What I really don't get is that everything was working swimmingly until I implemented those last three key events, and then this error started happening.

I think the error comes from the window procedure but I don't see where.

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
LRESULT CALLBACK uw::WindowBase::s_SubProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	EventStruct evt = {(WindowBase*)GetWindowLongPtr(hwnd, GWLP_USERDATA)};

	switch (msg)
	{
	case WM_DESTROY:
		if (evt.WinObj->DoEvent(EVENT_ONDESTROY, &evt))
			return 0;

		break;

	case WM_MOVE:
	case WM_MOVING:
		GetWindowRect(evt.WinObj->m_Window, &evt.WinObj->m_WindowRect);
		GetClientRect(evt.WinObj->m_Window, &evt.WinObj->m_ClientRect);
		
		if (evt.WinObj->DoEvent(EVENT_ONMOVE, &evt))
			return 0;

		break;

	case WM_SIZE:
	case WM_SIZING:
		GetWindowRect(evt.WinObj->m_Window, &evt.WinObj->m_WindowRect);
		GetClientRect(evt.WinObj->m_Window, &evt.WinObj->m_ClientRect);

		if (evt.WinObj->DoEvent(EVENT_ONSIZE, &evt))
			return 0;

		break;


	case WM_LBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_RBUTTONDOWN:

		evt.MouseEvent.CursorPos.x = GET_X_LPARAM(lparam);
		evt.MouseEvent.CursorPos.y = GET_Y_LPARAM(lparam);

		if (msg == WM_LBUTTONDOWN)
			evt.MouseEvent.Button = VK_LBUTTON;
		else if (msg == WM_MBUTTONDOWN)
			evt.MouseEvent.Button = VK_MBUTTON;
		else if (msg == WM_RBUTTONDOWN)
			evt.MouseEvent.Button = VK_RBUTTON;

		if (evt.WinObj->DoEvent(EVENT_ONMOUSEPRESS, &evt))
			return 0;

		break;

	case WM_LBUTTONUP:
	case WM_MBUTTONUP:
	case WM_RBUTTONUP:

		evt.MouseEvent.CursorPos.x = GET_X_LPARAM(lparam);
		evt.MouseEvent.CursorPos.y = GET_Y_LPARAM(lparam);

		if (msg == WM_LBUTTONUP)
			evt.MouseEvent.Button = VK_LBUTTON;
		else if (msg == WM_MBUTTONUP)
			evt.MouseEvent.Button = VK_MBUTTON;
		else if (msg == WM_RBUTTONUP)
			evt.MouseEvent.Button = VK_RBUTTON;

		if (evt.WinObj->DoEvent(EVENT_ONMOUSERELEASE, &evt))
			return 0;

		break;

	case WM_MOUSEMOVE:
		evt.MouseEvent.CursorPos.x = GET_X_LPARAM(lparam);
		evt.MouseEvent.CursorPos.y = GET_Y_LPARAM(lparam);

		if (evt.WinObj->DoEvent(EVENT_ONMOUSEMOVE, &evt))
			return 0;

		break;

	case WM_MOUSEWHEEL:
		evt.MouseEvent.WheelDelta = GET_WHEEL_DELTA_WPARAM(wparam);
		evt.MouseEvent.CursorPos.x = GET_X_LPARAM(lparam);
		evt.MouseEvent.CursorPos.y = GET_Y_LPARAM(lparam);

		if (evt.WinObj->DoEvent(EVENT_ONMOUSEWHEEL, &evt))
			return 0;

		break;

	case WM_KEYDOWN:
		evt.KeyEvent.Key = wparam;

		if (evt.WinObj->DoEvent(EVENT_ONKEYPRESS, &evt))
			return 0;

		break;

	case WM_KEYUP:
		evt.KeyEvent.Key = wparam;

		if (evt.WinObj->DoEvent(EVENT_ONKEYRELEASE, &evt))
			return 0;

		break;

	case WM_CHAR:
		evt.KeyEvent.Char = (WCHAR)wparam;

		if (evt.WinObj->DoEvent(EVENT_ONKEYCHAR, &evt))
			return 0;

		break;

	case WM_ERASEBKGND:
		if (evt.WinObj->DoEvent(EVENT_ONERASE, &evt))
			return TRUE;

		break;

	case WM_PAINT:
		if (evt.WinObj->DoEvent(EVENT_ONPAINT, &evt))
			return 0;

		break;

	case WM_SETTEXT:
		// (LPWSTR)lparam
		break;
	}

	return evt.WinObj->m_DefProc(hwnd, msg, wparam, lparam);
}
Wanna know something funny? I struggled with this error for hours only to find the solution almost instantly after posting this topic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	struct MouseEventStruct {
		WindowBase* WinObj;
		INT Button;
		INT WheelDelta;
		POINT CursorPos;
	};

	struct KeyEventStruct {            // <---- was missing WindowBase* WinObj
		INT Key;
		WCHAR Char;
	};

	union EventStruct {
		WindowBase* WinObj;
		MouseEventStruct MouseEvent;
		KeyEventStruct KeyEvent;
	};
Topic archived. No new replies allowed.