object 超出 switch case 范围时的访问冲突
Access violation when the object goes out of scope in switch case
好的,那么。我开始学习 C++,我的任务是用 Win32 API 创建一个进程管理器。它看起来像这样:
我有一个 TBuffer
class:(缓冲区将保留有关进程的信息)
#pragma once
#include <wtypes.h>
#define BUFFER_SIZE 10
#define WM_UPDATELIST WM_USER
enum TProcessState { psEmpty, psNew, psRunning, psTerminated, psError };
struct TProcessInfo
{
TProcessState State;
char Name[100];
HANDLE Handle;
int PID;
int UserTime, KenelTime;
};
class TBuffer
{
private:
HWND Wnd;
CRITICAL_SECTION cs;
TProcessInfo Buf[BUFFER_SIZE];
public:
TBuffer(HWND AWnd);
~TBuffer();
int Count();
int AddProcess(char *AName);
void Get(int Id, TProcessInfo &Pi);
void Set(int Id, const TProcessInfo Pi);
const char* ProcessStateToString(TProcessState state);
};
class构造函数实现如下:
TBuffer::TBuffer(HWND AWnd)
{
Wnd = AWnd;
InitializeCriticalSection(&cs);
for (int i = 0; i < BUFFER_SIZE; i++)
{
Buf[i].State = psEmpty;
Buf[i].Handle = 0;
Buf[i].Name[0] = 0;
Buf[i].PID = 0;
Buf[i].UserTime = 0;
Buf[i].Handle = 0;
}
}
以及析构函数:
TBuffer::~TBuffer()
{
DeleteCriticalSection(&cs);
}
使用临界区的方法:
void TBuffer::Set(int Id, const TProcessInfo Pi)
{
EnterCriticalSection(&cs);
...
LeaveCriticalSection(&cs);
}
在主 .cpp
文件中,我有一个全局变量:
TBuffer *Buffer;
并且在处理消息的MainWndProc
函数中,在WM_INITDIALOG
的情况下,我被要求创建一个TBuffer
classobject来初始化关键部分等等:
case WM_INITDIALOG:
{
TBuffer Buf(hWnd);
Buffer = &Buf;
...
return TRUE;
}
我的问题是,正如我所读,return TRUE
之后的 class object 超出范围并调用其析构函数。这就是为什么关键部分被删除,然后其他 Set()
和 Get()
等 class 方法无法进入关键部分的原因。所以我正在寻找一种将 object 留在范围内的方法。我认为 WM_INITDIALOG
和 object 创作有问题。
顺便说一句,在处理 WM_DESTROY
消息时,我释放了为全局变量分配的内存:
case WM_DESTROY:
delete[] Buffer;
PostQuitMessage(0);
return TRUE;
你的理解是正确的,
case WM_INITDIALOG:
{
TBuffer Buf(hWnd);
Buffer = &Buf;
...
return TRUE; // <-- Buf is destructed here, Buffer is now a dangling pointer
}
要分配比其封闭范围寿命更长的东西,请使用 new
:
在堆上分配它
case WM_INITDIALOG:
{
Buffer = new TBuffer(hWnd);
...
return TRUE;
}
记得以后delete
。
好的,那么。我开始学习 C++,我的任务是用 Win32 API 创建一个进程管理器。它看起来像这样:
我有一个 TBuffer
class:(缓冲区将保留有关进程的信息)
#pragma once
#include <wtypes.h>
#define BUFFER_SIZE 10
#define WM_UPDATELIST WM_USER
enum TProcessState { psEmpty, psNew, psRunning, psTerminated, psError };
struct TProcessInfo
{
TProcessState State;
char Name[100];
HANDLE Handle;
int PID;
int UserTime, KenelTime;
};
class TBuffer
{
private:
HWND Wnd;
CRITICAL_SECTION cs;
TProcessInfo Buf[BUFFER_SIZE];
public:
TBuffer(HWND AWnd);
~TBuffer();
int Count();
int AddProcess(char *AName);
void Get(int Id, TProcessInfo &Pi);
void Set(int Id, const TProcessInfo Pi);
const char* ProcessStateToString(TProcessState state);
};
class构造函数实现如下:
TBuffer::TBuffer(HWND AWnd)
{
Wnd = AWnd;
InitializeCriticalSection(&cs);
for (int i = 0; i < BUFFER_SIZE; i++)
{
Buf[i].State = psEmpty;
Buf[i].Handle = 0;
Buf[i].Name[0] = 0;
Buf[i].PID = 0;
Buf[i].UserTime = 0;
Buf[i].Handle = 0;
}
}
以及析构函数:
TBuffer::~TBuffer()
{
DeleteCriticalSection(&cs);
}
使用临界区的方法:
void TBuffer::Set(int Id, const TProcessInfo Pi)
{
EnterCriticalSection(&cs);
...
LeaveCriticalSection(&cs);
}
在主 .cpp
文件中,我有一个全局变量:
TBuffer *Buffer;
并且在处理消息的MainWndProc
函数中,在WM_INITDIALOG
的情况下,我被要求创建一个TBuffer
classobject来初始化关键部分等等:
case WM_INITDIALOG:
{
TBuffer Buf(hWnd);
Buffer = &Buf;
...
return TRUE;
}
我的问题是,正如我所读,return TRUE
之后的 class object 超出范围并调用其析构函数。这就是为什么关键部分被删除,然后其他 Set()
和 Get()
等 class 方法无法进入关键部分的原因。所以我正在寻找一种将 object 留在范围内的方法。我认为 WM_INITDIALOG
和 object 创作有问题。
顺便说一句,在处理 WM_DESTROY
消息时,我释放了为全局变量分配的内存:
case WM_DESTROY:
delete[] Buffer;
PostQuitMessage(0);
return TRUE;
你的理解是正确的,
case WM_INITDIALOG:
{
TBuffer Buf(hWnd);
Buffer = &Buf;
...
return TRUE; // <-- Buf is destructed here, Buffer is now a dangling pointer
}
要分配比其封闭范围寿命更长的东西,请使用 new
:
case WM_INITDIALOG:
{
Buffer = new TBuffer(hWnd);
...
return TRUE;
}
记得以后delete
。