不断增加物理内存Visual C ++ CertGetCertificateChain

时间:2011-08-18 18:28:09

标签: c++ visual-c++ memory-management memory-leaks

我正在使用C ++和Visual Studio 2005。

我不知道为什么,我试图改变代码顺序,但这似乎很奇怪。运行一个简单的项目时,phisycal内存会增加。

//has to include crypt32.lib in links
#include <windows.h>

void memoryUP2( PCCERT_CONTEXT __pCert )
{
    PCCERT_CHAIN_CONTEXT     _pChainContext     = NULL;
    CERT_ENHKEY_USAGE        _EnhkeyUsage;
    CERT_USAGE_MATCH         _CertUsage;  
    CERT_CHAIN_PARA          _ChainPara;
    DWORD                    _dwFlags           = CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS; //0;

    _EnhkeyUsage.cUsageIdentifier = 0;
    _EnhkeyUsage.rgpszUsageIdentifier=NULL;
    _CertUsage.dwType = USAGE_MATCH_TYPE_AND;
    _CertUsage.Usage  = _EnhkeyUsage;
    _ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
    _ChainPara.RequestedUsage=_CertUsage;

    {
        if(!CertGetCertificateChain(
            NULL,                  // default engine
            __pCert,   // certificate ctx
            NULL,                  // time
            NULL,                  // default store
            &_ChainPara,            // use AND logic and enhanced key usage 
                                    //  as indicated in the ChainPara 
                                    //  data structure
            _dwFlags,
            NULL,                  // currently reserved
            &_pChainContext))       // return a pointer to the chain created
        {
            //Error... Do nothing
        }
    }

    if (_pChainContext != NULL)
    {
        CertFreeCertificateChain(_pChainContext);
    }
}

使用此功能,“内存不会增加”:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    for(int i=0;i<550000;++i)
    {

        PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                      (const BYTE *)myfile._data, 
                                                                      myfile._length);

        if(certCtx!=NULL)
            CertFreeCertificateContext(certCtx);
    }

    return 0;
}

使用此功能,“内存不断增加”:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    for(int i=0;i<80000;++i)
    {

        PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                      (const BYTE *)myfile._data, 
                                                                      myfile._length);
        memoryUP2(certCtx);

        if(certCtx!=NULL)
            CertFreeCertificateContext(certCtx);
    }

    return 0;
}

使用此功能,“内存不会增加”:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                      (const BYTE *)myfile._data, 
                                                                      myfile._length);
    for(int i=0;i<80000;++i)
    {
        memoryUP2(certCtx);
    }

    if(certCtx!=NULL)
            CertFreeCertificateContext(certCtx);

    return 0;
}

使用此功能,“内存不断增加”:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    for(int j=0;j<5000;j++)
    {
        PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                          (const BYTE *)myfile._data, 
                                                                          myfile._length);
        for(int i=0;i<50;++i)
        {
            memoryUP2(certCtx);
        }

        if(certCtx!=NULL)
                CertFreeCertificateContext(certCtx);
    }

    return 0;
}

如何在没有内存泄漏的情况下使用它?

for(int i=0;i<80000;++i)
{

    PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                  (const BYTE *)myfile._data, 
                                                                  myfile._length);
    memoryUP2(certCtx);

    if(certCtx!=NULL)
        CertFreeCertificateContext(certCtx);
}

为什么会这样?

更新#1

我认为这与CertCreateCertificateChainEngine相关,查看MSDN Creating a Certificate Chain

我将代码更改为:

void memoryUP2( PCCERT_CONTEXT __pCert )
{
    PCCERT_CHAIN_CONTEXT     _pChainContext     = NULL;
    CERT_ENHKEY_USAGE        _EnhkeyUsage;
    CERT_USAGE_MATCH         _CertUsage;  
    CERT_CHAIN_PARA          _ChainPara;
    DWORD                    _dwFlags           = CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS; //0;

    HCERTCHAINENGINE         hChainEngine;
    CERT_CHAIN_ENGINE_CONFIG ChainConfig;

    ChainConfig.cbSize = sizeof(CERT_CHAIN_ENGINE_CONFIG);
    ChainConfig.hRestrictedRoot= NULL ;
    ChainConfig.hRestrictedTrust= NULL ;
    ChainConfig.hRestrictedOther= NULL ;
    ChainConfig.cAdditionalStore=0 ;
    ChainConfig.rghAdditionalStore = NULL ;
    ChainConfig.dwFlags = CERT_CHAIN_CACHE_END_CERT;
    ChainConfig.dwUrlRetrievalTimeout= 0 ;
    ChainConfig.MaximumCachedCertificates=0 ;
    ChainConfig.CycleDetectionModulus = 0;

    CertCreateCertificateChainEngine(
         &ChainConfig,
         &hChainEngine);

    _EnhkeyUsage.cUsageIdentifier = 0;
    _EnhkeyUsage.rgpszUsageIdentifier=NULL;
    _CertUsage.dwType = USAGE_MATCH_TYPE_AND;
    _CertUsage.Usage  = _EnhkeyUsage;
    _ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
    _ChainPara.RequestedUsage=_CertUsage;

    {
        if(!CertGetCertificateChain(
            NULL,                  // default engine
            __pCert,   // certificate ctx
            NULL,                  // time
            NULL,                  // default store
            &_ChainPara,            // use AND logic and enhanced key usage 
                                    //  as indicated in the ChainPara 
                                    //  data structure
            _dwFlags,
            NULL,                  // currently reserved
            &_pChainContext))       // return a pointer to the chain created
        {
            //Error... Do nothing
        }
    }

    if (_pChainContext != NULL)
    {
        CertFreeCertificateChain(_pChainContext);
        _pChainContext = NULL;
    }

    CertFreeCertificateChainEngine(hChainEngine);
}

记忆“不增加”只“很少”。

为什么默认引擎导致内存泄漏?
为什么声明引擎并使用CertGetCertificateChain(NULL,...)param?

0 个答案:

没有答案