c++ - 调用 Windows API 的 C++ 控制台程序中的内存泄漏

标签 c++ console-application

我复制了一些我在网上找到的代码here .我已经成功运行了它,但是如果我循环运行它,就会出现严重的内存泄漏。我主要使用 C# 编程,这个例子让我难以理解。有人能指出我修复内存泄漏的正确方向吗?这是我的完整 C++ 控制台应用程序。任何帮助表示赞赏。谢谢。

// ConsoleApplication1.cpp : Defines the entry point for the console     application.
//

#include "stdafx.h"
#include <iostream>
#include "Netlistmgr.h"




bool checkForCaptivePortalMode()
{
bool fCaptivePortalDetected = false;

// Initialize COM.
if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
    // Declare a pointer to INetworkListManager
    INetworkListManager* pNetworkListManager;

    // Create instance of the CLSID_NetworkListManger COM object
    if (SUCCEEDED(CoCreateInstance(CLSID_NetworkListManager, NULL,
        CLSCTX_ALL, IID_INetworkListManager,
        (LPVOID*)&pNetworkListManager)))
    {
        // Declare pointer to an IEnumNetworkConnections
        IEnumNetworks* pEnum;

        // Call to GetNetworks from INetworkListManager interface
        if (SUCCEEDED(pNetworkListManager->GetNetworks
        (NLM_ENUM_NETWORK_CONNECTED, &pEnum)) && pEnum != NULL)
        {
            INetwork *pINetwork;
            HRESULT hr = pEnum->Next(1, &pINetwork, nullptr);
            while (hr == S_OK)
            {
                if (pINetwork != NULL)
                {
                    IPropertyBag *pNetworkPropertyBag;
                    HRESULT hrQueryInterface = pINetwork->QueryInterface
                    (IID_IPropertyBag, (LPVOID*)&pNetworkPropertyBag);
                    if (SUCCEEDED(hrQueryInterface) && pNetworkPropertyBag != nullptr)
                    {
                        NLM_CONNECTIVITY networkConnectivity;
                        VARIANT variantConnectivity;

                        if (SUCCEEDED(pINetwork->GetConnectivity(&networkConnectivity)))
                        {
                            if ((networkConnectivity &
                                NLM_CONNECTIVITY_IPV4_INTERNET) == NLM_CONNECTIVITY_IPV4_INTERNET)
                            {
                                VariantInit(&variantConnectivity);
                                if (SUCCEEDED(pNetworkPropertyBag->Read
                                (NA_InternetConnectivityV4, &variantConnectivity, nullptr))
                                    && (V_UINT(&variantConnectivity) &
                                        NLM_INTERNET_CONNECTIVITY_WEBHIJACK) ==
                                    NLM_INTERNET_CONNECTIVITY_WEBHIJACK)
                                {
                                    fCaptivePortalDetected = true;
                                }
                                auto t = V_UINT(&variantConnectivity);
                                VariantClear(&variantConnectivity);
                            }
                            if (!fCaptivePortalDetected && (networkConnectivity
                                & NLM_CONNECTIVITY_IPV6_INTERNET) == NLM_CONNECTIVITY_IPV6_INTERNET)
                            {
                                VariantInit(&variantConnectivity);
                                if (SUCCEEDED(pNetworkPropertyBag->Read(NA_InternetConnectivityV6,
                                    &variantConnectivity, nullptr)) &&
                                    (V_UINT(&variantConnectivity) &
                                        NLM_INTERNET_CONNECTIVITY_WEBHIJACK) ==
                                    NLM_INTERNET_CONNECTIVITY_WEBHIJACK)
                                {
                                    fCaptivePortalDetected = true;
                                }
                                VariantClear(&variantConnectivity);
                            }
                        }
                    }

                    pINetwork->Release();
                }

                if (fCaptivePortalDetected)
                    break;


                hr = hr = pEnum->Next(1, &pINetwork, nullptr);
            }
        }
    }
}

// Uninitialize COM.
// (This should be called on application shutdown.)
CoUninitialize();

return fCaptivePortalDetected;
}

int main()
{
for (;;)
{
    bool check = checkForCaptivePortalMode();
    std::cout << "\n" << check;
    //char c = std::getchar();
}

return 0;
}

最佳答案

一方面,您永远不会调用 pNetworkListManager->Release()。更一般地说,在 C++ 中,如果您不使用智能指针,则必须确保每个资源分配都有一个匹配的释放。如果您在整个过程中使用智能指针,它会更容易并且可能使您的代码更简单。

关于c++ - 调用 Windows API 的 C++ 控制台程序中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40954374/

相关文章:

c++ - 如何使用GTest测试命令行选项解析器

c++ - 如何防止基类指针下的派生类对象调用基类中定义但在派生中被覆盖的公共(public)非虚函数?

perl - 如何在不丢失程序退出代码的情况下使用 Test::More 在 perl 程序中测试 subs?

c# - 关于控制台应用程序返回的错误代码的最佳实践是什么?

C#:是否可以根据开关让单个应用程序充当控制台或 Windows 应用程序?

c++ - 如何将 QNetworkAccessManager 移植到 WebEngine?

c++ - 如何隐藏 libfreenect2 的输出消息?

函数指针作为参数的 C++ 问题

tfs - 是否可以使用某些控制台客户端在 TFS 中获取最新版本?

python - 从子进程启动时如何停止 Bottle Web 服务器