Я хотел бы создать программу, которая контролирует некоторые процессы. Для этого я создал структуру, содержащую процессы для мониторинга, другую структуру, которая содержит, какие процессы все еще работают, и поток, который выполняет эту работу. В потоке (struct, который содержит запущенные процессы) ProcArrayDisplay
, будет свободным() 'd, чтобы удалить структуру, а затем malloc()' d и снова заполнить. Я не уверен, если это лучший способ. И вот моя проблема. Если работает 2 или более процесса, я всегда получаю Access vioalation
.Как правильно перенаправить бесплатную() 'структуру d?
Я думаю, это связано с тем, что счетчик структуры является глобальной переменной, а когда Thread изменяет его, что-то идет не так. Я пытался использовать, Critical sections
и InterLockedIncrement/InterLockedDecrement
, но я все еще получаю Access violation
.
Так что я делаю неправильно, и как я должен делать это правильно?
Заранее благодарен!
Мой код:
#include <Windows.h>
#include <Conio.h>
#include <process.h>
#include <TlHelp32.h>
struct ProcToQuery
{
wchar_t * ProcessName;
wchar_t * DisplayName;
};
struct ProcToQuery **ProcArrayQuery = NULL;
int ProcArrayCountQuery = 0;
struct ProcToDisplay
{
wchar_t * ProcessName;
wchar_t * DisplayName;
};
struct ProcToDisplay **ProcArrayDisplay = NULL;
volatile long ProcArrayCountDisplay = 0;
typedef struct
{
BOOL bKill;
}PARAMS, *PPARAMS;
void AddItemsToQueryArray(wchar_t * ProcessName, wchar_t * DisplayName);
void AddItemsToDisplayArray(wchar_t * ProcessName, wchar_t * DisplayName);
void FreeStruct();
void FreeStructDisplay();
BOOL IsProcessRunning(wchar_t * ProcessName, wchar_t * DisplayName);
unsigned __stdcall Thread(void *ArgList);
int _tmain(int argc, _TCHAR* argv[])
{
AddItemsToQueryArray(L"notepad.exe", L"Notepad");
AddItemsToQueryArray(L"calc.exe", L"Calculator");
PARAMS params;
params.bKill = FALSE;
unsigned int ThreadId;
for (int i = 0; i < ProcArrayCountQuery; i++)
{
if (!IsProcessRunning(ProcArrayQuery[ i ]->ProcessName, ProcArrayQuery[ i ]->DisplayName))
{
// IsProcessRunning failed
return 1;
}
}
if (ProcArrayCountDisplay == 0)
{
printf("\nNone of the processes are running");
FreeStruct();
return 0;
}
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, Thread, ¶ms, 0, &ThreadId);
// do some work
Sleep(20000);
params.bKill = TRUE;
DWORD dwExitCode;
DWORD dwRet = WaitForSingleObject(hThread, 2000);
if (dwRet == WAIT_OBJECT_0)
{
// the thread has terminated
GetExitCodeThread(hThread, &dwExitCode);
printf("\nThread finished ExitCode = %d", dwExitCode);
}
else if (dwRet == WAIT_TIMEOUT)
{
// thread still active
GetExitCodeThread(hThread, &dwExitCode);
printf("\nThread still active ExitCode = %d", dwExitCode);
}
else if (dwRet == WAIT_FAILED)
{
printf("\nWaitForSingleObject failed = %d", GetLastError());
}
CloseHandle(hThread);
_getch();
return 0;
}
void AddItemsToQueryArray(wchar_t * ProcessName, wchar_t * DisplayName)
{
struct ProcToQuery **tmp = (struct ProcToQuery **)realloc(ProcArrayQuery, (ProcArrayCountQuery + 1) * sizeof(struct ProcToQuery *));
if (tmp == NULL)
{
return;
}
ProcArrayQuery = tmp;
ProcArrayQuery[ ProcArrayCountQuery ] = (struct ProcToQuery *)malloc(sizeof **ProcArrayQuery);
if (ProcArrayQuery[ ProcArrayCountQuery ] == NULL)
{
return;
}
ProcArrayQuery[ ProcArrayCountQuery ]->ProcessName = _wcsdup(ProcessName);
ProcArrayQuery[ ProcArrayCountQuery ]->DisplayName = _wcsdup(DisplayName);
ProcArrayCountQuery++;
}//AddItemsToQueryArray
void AddItemsToDisplayArray(wchar_t * ProcessName, wchar_t * DisplayName)
{
struct ProcToDisplay **tmp = (struct ProcToDisplay **)realloc(ProcArrayDisplay, (ProcArrayCountDisplay + 1) * sizeof(struct ProcToDisplay *));
if (tmp == NULL)
{
return;
}
ProcArrayDisplay = tmp;
ProcArrayDisplay[ ProcArrayCountDisplay ] = (struct ProcToDisplay *)malloc(sizeof **ProcArrayDisplay);
if (ProcArrayDisplay[ ProcArrayCountDisplay ] == NULL)
{
return;
}
ProcArrayDisplay[ ProcArrayCountDisplay ]->ProcessName = _wcsdup(ProcessName);
ProcArrayDisplay[ ProcArrayCountDisplay ]->DisplayName = _wcsdup(DisplayName);
ProcArrayCountDisplay++;
}//AddItemsToDisplayArray
void FreeStruct()
{
for (int i = 0; i < ProcArrayCountQuery; i++)
{
if (ProcArrayQuery[ i ]->DisplayName) free(ProcArrayQuery[ i ]->DisplayName);
if (ProcArrayQuery[ i ]->ProcessName) free(ProcArrayQuery[ i ]->ProcessName);
if (ProcArrayQuery[ i ]) free(ProcArrayQuery[ i ]);
}
free(ProcArrayQuery);
FreeStructDisplay();
free(ProcArrayDisplay);
}//FreeStruct
void FreeStructDisplay()
{
for (int i = 0; i < ProcArrayCountDisplay; i++)
{
if (ProcArrayDisplay[ i ]->ProcessName) free(ProcArrayDisplay[ i ]->ProcessName);
if (ProcArrayDisplay[ i ]->DisplayName) free(ProcArrayDisplay[ i ]->DisplayName);
if (ProcArrayDisplay[ i ]) free(ProcArrayDisplay[ i ]);
ProcArrayCountDisplay--;
}
}
BOOL IsProcessRunning(wchar_t * ProcessName, wchar_t * DisplayName)
{
PROCESSENTRY32 process;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
{
return FALSE;
}
ZeroMemory(&process, sizeof(process));
process.dwSize = sizeof(process);
if (Process32First(snapshot, &process))
{
do
{
if ((_wcsicmp(process.szExeFile, ProcessName) == 0))
{
printf("\n%ls is running", ProcessName);
AddItemsToDisplayArray(ProcessName, DisplayName);
}
} while (Process32Next(snapshot, &process) == TRUE);
}
else
{
// Process32First failed
CloseHandle(snapshot);
return FALSE;
}
CloseHandle(snapshot);
return TRUE;
}
unsigned __stdcall Thread(void *ArgList)
{
PPARAMS pparams;
pparams = (PPARAMS)ArgList;
while (!pparams->bKill)
{
// Request ownership of the critical section.
// EnterCriticalSection(&CriticalSection);
FreeStructDisplay();
printf("\n----------------------------------------------------");
for (int i = 0; i < ProcArrayCountQuery; i++)
{
if (!IsProcessRunning(ProcArrayQuery[ i ]->ProcessName, ProcArrayQuery[ i ]->DisplayName))
{
// IsProcessRunning failed
return 1;
}
}
if (ProcArrayCountDisplay == 0)
{
// no package to display
break;
}
// Release ownership of the critical section.
// LeaveCriticalSection(&CriticalSection);
Sleep(1000);
}
_endthread();
return 0;
}
'перераспределить свободный() 'd struct' ... ждать, вы ожидаете получить обратно' свободные() 'd данные? –
@SouravGhosh: Нет, я не хочу возвращать данные free() 'd. Я освобождаю структуру, поэтому она будет пустой, а затем снова заполняет ее malloc. Извините, если я не могу объяснить лучше, чего я хочу. Мой английский не самый лучший. – kampi
Не можете ли вы просто «ноль» ('memset') вашей структуры? Вы должны освободить его только тогда, когда знаете, что вам больше не нужно. Обратите внимание, что 'free' не пустует вашу структуру: он выделяет выделенное пространство как доступное для другого выделения. Также сузите соответствующие части кода. – Coconop