C++ 内存泄漏无法解决它C++;
由于malloc,我的代码中出现了内存泄漏。但是我有点困惑,因为指针和结构。有人能告诉我应该在哪里正确使用免费软件吗?如果我要找的程序正在运行或没有运行,这个函数会给我一个布尔值C++ 内存泄漏无法解决它C++;,c++,memory-leaks,free,C++,Memory Leaks,Free,由于malloc,我的代码中出现了内存泄漏。但是我有点困惑,因为指针和结构。有人能告诉我应该在哪里正确使用免费软件吗?如果我要找的程序正在运行或没有运行,这个函数会给我一个布尔值 typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER SpareLi1;
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;
}
您应该在函数中调用
free
,以释放用malloc
分配的内存(并用realloc
重新分配)
问题是函数中有几个退出点,所以应该注意在每个退出点释放内存
在C语言中,这通常是通过一个到公共出口点的goto
语句来解决的,在这里您可以完成所有的资源清理
但是,C++中你可以做得更好。例如,您可以使用智能指针,如std::unique\u ptr
:
auto buffer = std::make_unique< BYTE[] >(bufferSize);
auto buffer=std::使_唯一(bufferSize);
当智能指针实例超出范围时(例如,当函数返回时),分配的内存将自动释放
您可以使用unique\u ptr::get
方法获取指向已分配缓冲区的原始指针
另一种方法是使用std::vector
及其resize
方法。
如果要获取指向向量缓冲区中第一个元素的指针(元素连续存储),可以使用
vector::data
方法vector::size
将返回向量中的项数。同样,向量中的内存也会自动释放。您应该在函数中调用free
,以释放分配给malloc
(并重新分配给realloc
)的内存
问题是函数中有几个退出点,所以应该注意在每个退出点释放内存
在C语言中,这通常是通过一个到公共出口点的goto
语句来解决的,在这里您可以完成所有的资源清理
但是,C++中你可以做得更好。例如,您可以使用智能指针,如std::unique\u ptr
:
auto buffer = std::make_unique< BYTE[] >(bufferSize);
auto buffer=std::使_唯一(bufferSize);
当智能指针实例超出范围时(例如,当函数返回时),分配的内存将自动释放
您可以使用unique\u ptr::get
方法获取指向已分配缓冲区的原始指针
另一种方法是使用std::vector
及其resize
方法。
如果要获取指向向量缓冲区中第一个元素的指针(元素连续存储),可以使用
vector::data
方法vector::size
将返回向量中的项数。而且,向量中的内存也会自动释放。首先,您使用的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);
auto-pspid=std::使_唯一(bufferSize);
以及引用它的方式:pspid.get()
内存将自动释放:)首先,您使用的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);
auto-pspid=std::使_唯一(bufferSize);
以及引用它的方式:pspid.get()
内存将自动释放:)您可以在每个“return”语句之前释放分配的块
free(pspid);
return ...;
顺便说一下:
返回1;//错误
当您想要返回bool值时,您应该返回TRUE或FALSE,而不返回任何其他值。您可以在每个“return”语句之前释放分配的块
free(pspid);
return ...;
顺便说一下:
返回1;//错误
当您想要返回布尔值时,您应该返回TRUE或FALSE,而不返回任何其他值。如果您使用C++11
,那么您可以使用更好的情况,即智能指针,永远不会出现内存泄漏。(std::unique_ptr或std::shared_ptr)在头文件中。如果使用C++11
,则可以使用更好的情况,即智能指针,永远不会出现内存泄漏。头文件中的(std::unique_ptr或std::shared_ptr)。ULONG bufferSize=100;//我必须在(;;pspid=(pssystem\u PROCESS\u INFORMATION\u DETAILD)的(TRUE){status=pfnNtQuerySystemInformation(SystemProcessInformation,nullptr,0,&bufferSize)}if(status!=status\u INFO\u LENGTH\u MISMATCH){return 1;}bufferSize*=2;pspid=(pssystem\u PROCESS\u INFORMATION\u DETAILD)malloc(bufferSize);}(pspid->nexteryOffset+(PBYTE)pspid)){…int result=wcscmp(exe_name,name);if(result==0){free(pspid);return TRUE;}if(pspid->nexteryOffset==0)break;}free(pspid);return FALSE;看起来仍然错误,因为函数现在以1gb内存开始,并且不检查正在运行的进程。你能帮我一下吗?(Sry我不知道如何在评论中格式化文本)@PatrickHißler,不需要while
循环!直接在方法中执行此操作,请参阅我的更新答案。好的