由于malloc,我的代码中出现内存泄漏。但由于指针和结构,我有点困惑。谁能告诉我应该在哪里使用我的免费?如果我正在寻找的程序正在运行,这个函数给我一个bool值。
typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
}
SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD;
typedef NTSTATUS(WINAPI *PFN_NT_QUERY_SYSTEM_INFORMATION)(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT OPTIONAL PULONG ReturnLength);
BOOLEAN IsProcessRunning(TCHAR* exe_name)
{
size_t bufferSize = 10000;
PSYSTEM_PROCESS_INFORMATION_DETAILD pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)malloc(bufferSize);
ULONG ReturnLength;
PFN_NT_QUERY_SYSTEM_INFORMATION pfnNtQuerySystemInformation = (PFN_NT_QUERY_SYSTEM_INFORMATION)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
NTSTATUS status;
TCHAR* name;
while (TRUE)
{
status = pfnNtQuerySystemInformation(SystemProcessInformation, (PVOID)pspid, bufferSize, &ReturnLength);
if (status == STATUS_SUCCESS)
break;
else if (status != STATUS_INFO_LENGTH_MISMATCH)
{
return 1; // error
}
bufferSize *= 2;
pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)realloc((PVOID)pspid, bufferSize);
}
for (;; pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)(pspid->NextEntryOffset + (PBYTE)pspid))
{
name = (pspid->ImageName.Length && pspid->ImageName.Buffer) ? pspid->ImageName.Buffer : L"";
//_tprintf(_T("P-Id: %d, P-Name: %ls\n"), pspid->UniqueProcessId, name);
int result = wcscmp(exe_name, name);
if (result == 0)
{
return TRUE;
}
if (npspid->NextEntryOffset == 0) break;
}
return FALSE;
}
答案 0 :(得分:2)
您应该在函数中调用free
,以释放您使用malloc
分配的内存(并使用realloc
重新分配)。
问题是你的函数中有几个退出点,所以你应该注意在每个出口点释放内存。
在C中,这通常通过goto
语句解决到公共出口点,在那里您可以清理所有资源。
但是,在C ++中你可以做得更好。例如,您可以使用 smart 指针,例如std::unique_ptr
:
auto buffer = std::make_unique< BYTE[] >(bufferSize);
当智能指针实例超出范围时(例如,当函数返回时),分配的内存自动释放。
您可以使用unique_ptr::get
方法获取指向已分配缓冲区的原始指针。
另一种方法是使用std::vector<BYTE>
及其resize
方法。
如果要获取指向向量缓冲区中第一个元素的指针(元素是连续存储的),则可以使用vector::data
方法。 vector::size
将返回向量中的项目数。而且,矢量中的内存再次自动释放。
答案 1 :(得分:1)
首先,您正在使用Windows API:API的设计使您可以:
像这样:
BOOLEAN IsProcessRunning(TCHAR* exe_name)
{
ULONG bufferSize;
status = pfnNtQuerySystemInformation(SystemProcessInformation, nullptr, 0, &bufferSize);
if (status != STATUS_INFO_LENGTH_MISMATCH)
{
return 1;
}
pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)malloc(bufferSize);
ULONG bufferSize;
status = pfnNtQuerySystemInformation(SystemProcessInformation, (PVOID)pspid, bufferSize, nullptr);
if (status != STATUS_SUCCESS)
{
return 1;
}
for (..)
{
[..]
}
}
接下来,在完成for
循环中使用缓冲区后,您可以使用以下命令释放内存:
free(pspid);
更好的实施
更好的实现将使用智能指针。您需要更改的唯一事项是分配pspid
:
auto pspid = std::make_unique<BYTE[]>(bufferSize);
以及您引用它的方式:pspid.get()
内存将自动释放:)
答案 2 :(得分:0)
您可以在每个'return'语句之前释放已分配的块。
free(pspid);
return ...;
顺便说一下:
返回1; //错误
如果你想返回一个bool值,你应该返回TRUE或FALSE而不是别的。