内存泄漏无法解决C ++问题

时间:2017-10-19 09:40:58

标签: c++ memory-leaks free

由于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;
    }

3 个答案:

答案 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而不是别的。