Lorne
Lorne

Reputation: 99

memory leak in c++ console program calling Windows APIs

I have copied some code I found on-line here. I have successfully run it but if I run it in a loop, there is a bad memory leak. I program mostly in C#, and this example goes way over my head. Could somebody point me in the right direction to fixing the memory leak? Here is my C++ console application in it's entirety. Any help is appreciated. Thanks.

// 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;
}

Upvotes: 1

Views: 234

Answers (1)

John Zwinck
John Zwinck

Reputation: 249153

For one thing you never call pNetworkListManager->Release(). More generally, in C++ if you are not using smart pointers you must make sure each and every resource allocation has a matching deallocation. It would be easier and probably make your code simpler if you used smart pointers throughout.

Upvotes: 1

Related Questions