C++ 内存泄漏无法解决它C++;

C++ 内存泄漏无法解决它C++;,c++,memory-leaks,free,C++,Memory Leaks,Free,由于malloc,我的代码中出现了内存泄漏。但是我有点困惑,因为指针和结构。有人能告诉我应该在哪里正确使用免费软件吗?如果我要找的程序正在运行或没有运行,这个函数会给我一个布尔值 typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER SpareLi1;

由于malloc,我的代码中出现了内存泄漏。但是我有点困惑,因为指针和结构。有人能告诉我应该在哪里正确使用免费软件吗?如果我要找的程序正在运行或没有运行,这个函数会给我一个布尔值

   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
循环!直接在方法中执行此操作,请参阅我的更新答案。好的