Stack Around 'pfd' Corrupted

closed account (N36fSL3A)
Alright, so I've decided to just use WinAPI a while back, and things were working fine. Since I plan on porting my engine over to other platforms, I rewrote my window class (calling this one 'Context'). Anyway, with Visual Studio 2012 Express it's telling me the stack around 'pfd' is corrupted. (My pixel format descriptor). I never got this error before, I'm clueless. Here's my code:

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
		Context(const std::string name, std::string rName, unsigned int rW, unsigned int rH, void* param, void* param2 = nullptr)
		{
			for(unsigned int i = 0; i < 512; i++)
				keys.push_back(false);

			memset(&keys[0], 0, 512);
			
			data1 = nullptr;
			data2 = nullptr;
			data3 = nullptr;
			data4 = nullptr;

			resWidth  = rW;
			resHeight = rH;

			#if(_WIN32)
				pf = 0;

				WNDCLASSEX wcex;
				PIXELFORMATDESCRIPTOR pfd = 
				{
					sizeof(PIXELFORMATDESCRIPTOR),
					1,
					PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,    //Flags
					PFD_TYPE_RGBA,            //The kind of framebuffer. RGBA or palette.
					32,                        //Colordepth of the framebuffer.
					0, 0, 0, 0, 0, 0,
					0,
					0,
					0,
					0, 0, 0, 0,
					32,                        //Number of bits for the depthbuffer
					8,                        //Number of bits for the stencilbuffer
					0,                        //Number of Aux buffers in the framebuffer.
					PFD_MAIN_PLANE,
					0,
					0, 0, 0
				};

				// param is the hInstance
				// param2 is not used.
				data4 = param;

				memset(&wcex, 0, sizeof(WNDCLASSEX));

				HWND  hWnd = nullptr;
				HDC   hDC  = nullptr;
				HGLRC hRC  = nullptr;

				//std::wstring wclassName(rName.begin(), rName.end());

				wchar_t* wclassName = new wchar_t[rName.size()];

				for(unsigned int i = 0; i < rName.size(); i++)
					wclassName[i] = rName[i];

				wcex.cbSize = sizeof(WNDCLASSEX);
				wcex.cbClsExtra = 0;
				wcex.cbWndExtra = 0;
				wcex.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
				wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);          // Load The Default Icon
				wcex.hIcon   = LoadIcon  (nullptr, IDI_WINLOGO);
				wcex.hIconSm = nullptr;
				wcex.hInstance = (HINSTANCE)data4;
				wcex.lpfnWndProc = (WNDPROC)WndProc;
				wcex.lpszClassName = wclassName;
				wcex.lpszMenuName = nullptr;
				wcex.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;

				//Register Window Class
				DWORD e = GetLastError();
				if(!RegisterClassEx(&wcex)) {throw CF::Error("CF::Video::Context::Context() - Failure registering window class.");}
	
				//Create Windows
				hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
										wcex.lpszClassName,
										std::wstring(name.begin(), name.end()).c_str(),
										WS_BORDER,
										CW_USEDEFAULT,
										CW_USEDEFAULT, 
										resWidth,
										resHeight,
										nullptr,
										nullptr,
										wcex.hInstance,
										nullptr);

				if(!hWnd) {throw CF::Error("CF::Video::Context::Context() - Failure creating window.");}

				store::data = this;

				hDC = GetDC(hWnd);
				pf = ChoosePixelFormat(hDC, &pfd);

				if(pf == 0) {throw CF::Error("CF::Video::Context::Context() - Could not find pixel format.");}

				SetPixelFormat(hDC, pf, &pfd);

				// Get a context
				hRC = wglCreateContext(hDC);

				wglMakeCurrent(hDC, hRC);

				// Set the data pointers to the appropriate value
				data1 = hRC;
				data2 = hDC;
				data3 = hWnd;
				data4 = param;

				//Show Window and Update Window
				ShowWindow(hWnd, SW_SHOW);
				UpdateWindow(hWnd);

				delete[] wclassName;

			#endif
		}
Line 6 looks very suspect:

1
2
3
4
			for(unsigned int i = 0; i < 512; i++)
				keys.push_back(false);

			memset(&keys[0], 0, 512); // <- get rid of this 


If you're already filling the vector with 512 'false's, then why do you bother memsetting it immediately after that? If keys is a vector<bool>, then it's possible that memset might be overflowing your buffer. You are assuming that the vector stores each entry as a byte when that might not be the case.


As a general rule... don't use memset in C++ (or at least, avoid it when possible). std::fill would be better. And prefer iterators to getting a pointer to vector elements. This would be a lot safer than that memset:

1
2
3
4
//memset(&keys[0], 0, 512); // <- bad

std::fill(keys.begin(), keys.end(), false);  // <- better (although, no need for this really)
  // since you are push_backing all the falses immediately before this. 



Though I doubt that's your problem... as that would be heap corruption rather than stack corruption.

Your problem might be in the ChoosePixelFormat function, since that seems to be what's modifying pfd. Can you post that function as well?




Also... you're using the wrong character type. CreateWindowEx takes TCHARs, not wide chars. And you have narrow chars to begin with... so just use the narrow version of these functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
WNDCLASSEXA wcex; // <- add the 'A' to the end

//...
/* Can get rid of all this crap
wchar_t* wclassName = new wchar_t[rName.size()];

for(unsigned int i = 0; i < rName.size(); i++)
     wclassName[i] = rName[i];
*/

wcex.lpszClassName = rName; // <- and just use rName directly

//...
if(!RegisterClassExA(&wcex))  // <- add A to the end

hWnd = CreateWindowExA(WS_EX_OVERLAPPEDWINDOW,  // <- Another A to the end
        wcex.lpszClassName,
        //std::wstring(name.begin(), name.end()).c_str(),  // no need for wide conversion
        name.c_str(),  // <- just use name directly 


Remember:

no suffix = TCHAR
A suffix = char
W suffix = wchar_t

closed account (N36fSL3A)
ChoosePixelFormat is a WinAPI function.. I can't really show the code. Thanks for the other stuff.

EDIT: Yea that fixed that problem but now...

http://prntscr.com/2fk2d7

The line through the middle of the screen is intentional but the rest isn't...
Last edited on
For the weird ?chinese? characters at the top, it looks like you might be passing a narrow character string to a wide (or TCHAR) function.

Are you calling CreateWindowExA? (note the A at the end)
If you have narrow strings, throw A at the end of all of it:

CreateWindowExA
RegisterClassExA
WNDCLASSEXA
closed account (N36fSL3A)
I did that but I'll double check...

EDIT: Yea, from what I can see I added 'A's to the end.

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
		Context(const std::string name, std::string rName, unsigned int rW, unsigned int rH, void* param, void* param2 = nullptr)
		{
			for(unsigned int i = 0; i < 512; i++)
				keys.push_back(false);
			
			this->name  = name;
			this->rName = rName;

			data1 = nullptr;
			data2 = nullptr;
			data3 = nullptr;
			data4 = nullptr;

			resWidth  = rW;
			resHeight = rH;

			#if(_WIN32)
				store::data = this;

				pf = 0;

				WNDCLASSEXA wcex = {};
				PIXELFORMATDESCRIPTOR pfd = 
				{
					sizeof(PIXELFORMATDESCRIPTOR),
					1,
					PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,    //Flags
					PFD_TYPE_RGBA,            //The kind of framebuffer. RGBA or palette.
					32,                        //Colordepth of the framebuffer.
					0, 0, 0, 0, 0, 0,
					0,
					0,
					0,
					0, 0, 0, 0,
					32,                        //Number of bits for the depthbuffer
					8,                        //Number of bits for the stencilbuffer
					0,                        //Number of Aux buffers in the framebuffer.
					PFD_MAIN_PLANE,
					0,
					0, 0, 0
				};

				// param is the hInstance
				// param2 is not used.
				data4 = param;

				HWND  hWnd = nullptr;
				HDC   hDC  = nullptr;
				HGLRC hRC  = nullptr;

				wcex.cbSize = sizeof(WNDCLASSEXA);
				wcex.cbClsExtra = 0;
				wcex.cbWndExtra = 0;
				wcex.hbrBackground = nullptr;
				wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);          // Load The Default Icon
				wcex.hIcon   = LoadIcon  (nullptr, IDI_WINLOGO);
				wcex.hIconSm = nullptr;
				wcex.hInstance = (HINSTANCE)data4;
				wcex.lpfnWndProc = WndProc;
				wcex.lpszClassName = rName.c_str();
				wcex.lpszMenuName = nullptr;
				wcex.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;

				//Register Window Class
				DWORD e = GetLastError();
				if(!RegisterClassExA(&wcex)) {throw CF::Error("CF::Video::Context::Context() - Failure registering window class.");}
	
				//Create Windows
				hWnd = CreateWindowExA(WS_EX_OVERLAPPEDWINDOW,
										wcex.lpszClassName,
										name.c_str(),
										WS_BORDER,
										CW_USEDEFAULT,
										CW_USEDEFAULT, 
										resWidth,
										resHeight,
										nullptr,
										nullptr,
										wcex.hInstance,
										nullptr);

				if(!hWnd) {throw CF::Error("CF::Video::Context::Context() - Failure creating window.");}

				hDC = GetDC(hWnd);
				pf = ChoosePixelFormat(hDC, &pfd);

				if(pf == 0) {throw CF::Error("CF::Video::Context::Context() - Could not find pixel format.");}

				SetPixelFormat(hDC, pf, &pfd);

				// Get a context
				hRC = wglCreateContext(hDC);

				wglMakeCurrent(hDC, hRC);

				// Set the data pointers to the appropriate value
				data1 = hRC;
				data2 = hDC;
				data3 = hWnd;
				data4 = param;

				//Show Window and Update Window
				ShowWindow(hWnd, SW_SHOW);
				UpdateWindow(hWnd);

			#endif
		}
Last edited on
This may be a silly question.. but are you sure your 'name' string isn't garbage?
closed account (N36fSL3A)
Yes, I'm sure. I even hardcoded in 'name' with a char* to make sure it wasn't.
I see you aren't checking if line 85 is successful. Given line 29, I would expect line 85 to fail. With PFD_TYPE_RGBA, that number should be the number of bits used to represent color (excluding bits used to represent alpha.) I don't think most graphic cards will have support 32 bits of color + alpha.

You're missing a few checks for things that can fail. You should rectify that.
Topic archived. No new replies allowed.