类内部私有数组的访问冲突
Access violation on a private array inside a class
For the most part this is borrowed code from RasterTeks DX11 tutorial that I am modified lightly or my own use and taste. I am getting a read access violation while using the below InputClass to set keystates.
#include "InputClass.h"
InputClass::InputClass() { }
InputClass::InputClass(const InputClass& other) { }
InputClass::~InputClass() { }
void InputClass::Initialize() {
// Initialize all the keys to being released and not pressed.
for (int i = 0; i<256; i++) {
keystate[i] = false;
}
return;
}
void InputClass::KeyDown(unsigned int input) {
// If a key is pressed then save that state in the key array.
keystate[input] = true;
return;
}
void InputClass::KeyUp(unsigned int input) {
// If a key is released then clear that state in the key array.
keystate[input] = false;
return;
}
bool InputClass::IsKeyDown(unsigned int input) {
// Return what state the key is in (pressed/not pressed).
return keystate[input];
}
下面是我的主回调循环,一个注册在WindowClass:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// this message is read when the window is closed
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE: {
PostQuitMessage(0);
return 0;
}
default: { return ApplicationHandle->MessageHandler(hWnd, message, wParam, lParam); }
}
}
最后,下面是第二个消息处理程序,它是我的SystemClass的一部分:
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_KEYDOWN: { input->KeyDown((unsigned int)wparam); }
case WM_KEYUP: { input->KeyUp((unsigned int)wparam); }
default: { return DefWindowProc(hwnd, message, wparam, lparam); }
}
}
当代码到达次要消息处理程序中的switch/case/default列表时,异常被触发。如果我注释掉这些行,程序会正常运行,当然,没有输入。
任何帮助或线索都是无价的。非常感谢您的宝贵时间。尝试如下修改代码:
void InputClass::KeyDown(unsigned int input) {
if (input < 0 || input > 255)
return;
// If a key is pressed then save that state in the key array.
keystate[input] = true;
return;
}
void InputClass::KeyUp(unsigned int input) {
if (input < 0 || input > 255)
return;
// If a key is released then clear that state in the key array.
keystate[input] = false;
return;
}
(由于InputClass
的构造函数没有任何问题,因此它不是数组私有状态的问题)
我试了一下,运气不好。我将保留代码,以防出错,但它在相同的地方调用了访问冲突。
我将包括下面缺失的信息。
//inputclass.h
class InputClass
{
public:
InputClass();
InputClass(const InputClass&);
~InputClass();
void Initialize();
void KeyDown(unsigned int);
void KeyUp(unsigned int);
bool IsKeyDown(unsigned int);
//private:
bool keystate[256];
};
//systemclass.h
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <windowsx.h>
#include "InputClass.h"
class SystemClass {
public:
SystemClass();
~SystemClass();
void Startup();
bool InitializeWindows(HWND);
void ShutDown();
void Run();
LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
int GetWindowPosX();
int GetWindowPosY();
int GetWindowWidth();
int GetWindowHeight();
private:
HWND hWnd;
InputClass* input;
int posX, posY, windowWidth, windowHeight;
};
static SystemClass* ApplicationHandle = 0;
//main.cpp
#include "systemclass.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviousInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
SystemClass* system;
system = new SystemClass;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"Engine";
RegisterClassEx(&wc);
system->Startup();
if(!(system->InitializeWindows(CreateWindowEx(NULL,
L"Engine",
L"Engine",
WS_POPUP | WS_VISIBLE,
system->GetWindowPosX(),
system->GetWindowPosY(),
system->GetWindowWidth(),
system->GetWindowHeight(),
NULL,
NULL,
hInstance,
NULL)))) return 0;
system->Run();
system->ShutDown();
UnregisterClass(L"Engine", hInstance);
delete system;
system = 0;
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// this message is read when the window is closed
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE: {
PostQuitMessage(0);
return 0;
}
default: { return ApplicationHandle->MessageHandler(hWnd, message, wParam, lParam); }
}
}
//systemclass.cpp
#include "SystemClass.h"
SystemClass::SystemClass() { }
SystemClass::~SystemClass() { }
void SystemClass::Startup() {
ApplicationHandle = this;
windowWidth = GetSystemMetrics(SM_CXSCREEN);
windowHeight = GetSystemMetrics(SM_CYSCREEN);
input = new InputClass;
input->Initialize();
int fc = MessageBox(NULL, L"Engine", L"Fullscreen?", MB_YESNO);
switch (fc) {
case 7: {
posX = (windowWidth - 800) / 2;
posY = (windowHeight - 600) / 2;
windowWidth = 800;
windowHeight = 600;
}
case 6: {
DEVMODE dmScreenSettings;
posX = posY = 0;
ZeroMemory(&dmScreenSettings, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)windowWidth;
dmScreenSettings.dmPelsHeight = (unsigned long)windowHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Change the display settings to full screen.
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
}
}
bool SystemClass::InitializeWindows(HWND ihWnd) {
hWnd = ihWnd;
if (hWnd) {
//system->InitializeWindows(hWnd);
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
return true;
}
else {
MessageBoxEx(NULL, L"Could not create window.", L"ERROR!", MB_OK | MB_ICONEXCLAMATION, NULL);
return false;
}
}
void SystemClass::ShutDown() {
delete input;
input = 0;
DestroyWindow(hWnd);
hWnd = NULL;
ApplicationHandle = NULL;
}
void SystemClass::Run() {
bool done;
MSG msg;
done = false;
while (!done) {
// Handle the windows messages.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (input->IsKeyDown(VK_ESCAPE)) {
done = true;
MessageBoxEx(NULL, L"input broken.", L"ERROR!", MB_OK | MB_ICONEXCLAMATION, NULL);
}
// If windows signals to end the application then exit out.
if (msg.message == WM_QUIT) { done = true; }
}
}
int SystemClass::GetWindowPosX(){ return posX; }
int SystemClass::GetWindowPosY() { return posY; }
int SystemClass::GetWindowWidth() { return windowWidth; }
int SystemClass::GetWindowHeight() { return windowHeight; }
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_KEYDOWN: { input->KeyDown((unsigned int)wparam); }
case WM_KEYUP: { input->KeyUp((unsigned int)wparam); }
default: { return DefWindowProc(hwnd, message, wparam, lparam); }
}
}
当我按下转义键时给出的错误信息:0xC0000005:访问违反读取位置0x00000004.
OK:这就是它变得有趣的地方,本地字段中的值(特定于第二个回调函数)如下:lparam: 65537按钮:27消息:256Hwnd: 0x01b80460{未使用=??}这:0x00000000
hwnd、wparam、lparam的值都以红色显示。
我觉得这些值应该告诉我这里发生了什么,但我真的不明白。变量"this"设置为地址0x00000000是否有原因?这是一个指向systemclass实例的指针…或者它应该是。
同样,hwnd中未使用的注释使我感到困惑,尽管我不确定那里出了什么问题,因为程序非常清楚地至少检测到归因于窗口的按键。
我希望这对大家有帮助。
编辑:你让我寻找一个被滥用的指针,我发现它与"this"指针和我使用system和ApplicationHandle的方式有关。我通过将ApplicationHandle更改为system并在任何地方简单地使用相同的指针来修复它。我以前使用它的方式是不合逻辑的,毫无意义的。
谢谢大家帮我找到它!
- 按字符值访问int数组
- C++ - 循环访问指针数组会导致错误
- 通过unique_ptr访问std::数组
- 为什么我无法访问指向数组中成员函数的指针?
- 在函数 strcpy() 中访问字符数组时出现分段错误
- 在 C++ 中访问 JSON 数组值
- 在C++中访问结构数组中的数据
- C++:在多个线程中访问同一数组/向量的不同单元格是否会产生数据竞赛?
- 是否可以使用宏来访问动态数组或向量中的元素或为其赋值
- 从类访问char数组
- 更快地访问 C++ 数组中的随机元素
- 如何修复访问动态数组中结构中的字符串变量时"segmentation fault (core dumped)"错误
- 在C++中使用 RapidJSON 访问 JSON 数组的字段
- 创建 2D 数组类:如何访问 2D 数组类(如 array[x][y))中的元素
- 通过矢量下标访问 Fortran 数组,相当于 cpp
- 在能够从 Web 浏览器访问大型数组数据的同时存储它的最可行方法是什么?
- 有没有办法使用初始化到第一行的指针访问 2d 数组的第二行?
- 通过C++中的指针访问字符数组
- C++ 如何使用类方法正确访问动态数组元素
- 访问 2D 数组时的读取冲突