DetailPage-MSS-KB

Base de Dados de Conhecimento

Artigo: 271926 - Última revisão: quinta-feira, 11 de Dezembro de 2003 - Revisão: 2.0

 

Nesta página

Sintomas

Os métodos de seguintes modelo de consumidor de biblioteca de modelo de Active Directory (ATL) OLE DB não correctamente versão atribuída memória e assim causam uma fuga de memória:
  • OpenWithPromptFileName
  • OpenFromFileName
  • GetInitializationString
Estes são os métodos da classe CDataSource , que é definido no ficheiro de cabeçalho Atldbcli.h.

Causa

Estes métodos CDataSource não libertar memória para uma cadeia que foi atribuída para os mesmos. Estes métodos chamam funções OLE DB que atribuir a memória para a cadeia e preenchê-lo. As funções de OLE DB chamar a função CoTaskMemAlloc atribuir memória para a cadeia e o emissor de consumidor ATL OLE DB obtém a cadeia novamente como resultado.

É da responsabilidade do emissor para esta memória. Nesta situação, o código ATL é o autor da chamada. Não liberta a cadeia depois que é utilizado, que faz com que a fuga de memória.

Resolução

Uma solução consiste em Adicionar código para libertar memória atribuída para a cadeia na fim de cada um dos métodos acima listados. O seguinte código ilustra esta solução alternativa:
HRESULT GetInitializationString(BSTR* pInitializationString, bool bIncludePassword=false)
{
        	// If the datasource isn't open, we're not going to get an init string.
	_ASSERTE(m_spInit != NULL);
	CComPtr<IDataInitialize> spDataInit;
	LPOLESTR    szInitString;
	HRESULT hr = CoCreateInstance(CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER,
		IID_IDataInitialize, (void**)&spDataInit);
	if (FAILED(hr))
		return hr;
	hr = spDataInit->GetInitializationString(m_spInit, bIncludePassword, &szInitString);

	if (SUCCEEDED(hr))
	        *pInitializationString = ::SysAllocString(szInitString);

	// Free the string here.
	if(szInitString) CoTaskMemFree((void*)szInitString);
	return hr;
}

HRESULT OpenWithPromptFileName(HWND hWnd = GetActiveWindow(),
                               DBPROMPTOPTIONS dwPromptOptions = DBPROMPTOPTIONS_NONE,
                               LPCOLESTR szInitialDirectory = NULL)
{
	USES_CONVERSION;
	CComPtr<IDBPromptInitialize> spDBInit;

	HRESULT hr = CoCreateInstance(CLSID_DataLinks, NULL, CLSCTX_INPROC_SERVER,
		IID_IDBPromptInitialize, (void**) &spDBInit);
	if (FAILED(hr))
		return hr;

	CComPtr<IDBProperties> spIDBProperties;
	LPOLESTR szSelected;

	hr = spDBInit->PromptFileName(hWnd,
                                       dwPromptOptions,
                                       szInitialDirectory,
                                       L"*.udl",
                                       &szSelected);

	if (hr == S_OK)
		hr = OpenFromFileName(szSelected);
	else if (hr == S_FALSE) // The user clicked cancel.
		hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_CANCELLED);

	// Free the string here.
	if(szSelected) CoTaskMemFree((void*)szSelected);

	return hr;
}

HRESULT OpenFromFileName(LPCOLESTR szFileName)
{
	CComPtr<IDataInitialize> spDataInit;
	LPOLESTR                 szInitString;

	HRESULT hr = CoCreateInstance(CLSID_MSDAINITIALIZE,
                                       NULL,
                                       CLSCTX_INPROC_SERVER,
                                       IID_IDataInitialize,
                                       (void**)&spDataInit);
	if (FAILED(hr))
	   return hr;

	hr = spDataInit->LoadStringFromStorage(szFileName,&szInitString);
	if (FAILED(hr))
 	   return hr;

	hr = OpenFromInitializationString(szInitString);
	if (FAILED(hr))
            return hr;

	//Done with the szInitString, so free the string here.
	if(szInitString) CoTaskMemFree((void*)szInitString);

        return hr;
}
				
para modificar o ficheiro de cabeçalho, execute os seguintes passos:
  1. Atldbcli.h é o ficheiro principal que contém a implementação de classes de modelo de consumidor ATL OLE DB. É aconselhável efectuar uma cópia deste ficheiro de cabeçalho na pasta do projecto local e modificá-lo directamente existe.
  2. Não se esqueça de # incluir o novo ficheiro de cabeçalho no projecto, em vez do ficheiro Atldbcli.h original.
  3. Confirme que a aplicação está a utilizar a versão modificada do ficheiro de cabeçalho, definir um ponto de interrupção das funções revistas e verificar se é ou não for seleccionado o ponto de interrupção.

Ponto Da Situação

A Microsoft confirmou que este erro ocorre nos produtos da Microsoft listados no início deste artigo.

Mais Informação

Passos para reproduzir o comportamento

  1. Crie um ficheiro .udl denominado Connection1.udl. Para obter informações adicionais sobre como criar ficheiros .udl, clique os números de artigo existente abaixo para visualizar os artigos na base de dados de conhecimento da Microsoft:
    244659  (http://support.microsoft.com/kb/244659/EN-US/ ) MDAC 2.5 exemplo de como criar um ficheiro de ligação de dados com o Windows 2000
    195913  (http://support.microsoft.com/kb/195913/EN-US/ ) COMO: Gerar ODBC e cadeias de ligação OLEDB com ligações de dados
  2. No Visual C++, crie uma nova aplicação de consola Win32 e adicione o seguinte código:
    #include <atldbcli.h>
    void main()
    {
    	CoInitialize(NULL);	
    	while(true){
    		CDataSource db;
    		HRESULT  hr;
    		BSTR bstr;
    		
    		//hr = db.OpenWithPromptFileName();
    		hr = db.OpenFromFileName(L"connection1.udl");
    		if( hr != S_OK ) MessageBox(0,"Failure in OpenFromFileName","",1);
    		
    		hr = db.GetInitializationString(&bstr);
    		if( hr != S_OK ) MessageBox(0,"Failure in GetInitializationString","",1);
    		if(bstr) CoTaskMemFree((void*)bstr);
    
    		db.Close();
    	}
    	CoUninitialize();
    }
    					
  3. Criar e executar a aplicação. Como é executado, pode utilizar o Monitor de desempenho (PerfMon) do Microsoft Windows NT para ver a utilização da memória aumentar, monitorizando os bytes de privados são utilizados por este processo.

A informação contida neste artigo aplica-se a:
  • Microsoft ActiveX Template Library 3.0 nas seguintes plataformas
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
Palavras-chave: 
kbmt kbbug kbconsumer kbdtl KB271926 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática… erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 271926  (http://support.microsoft.com/kb/271926/en-us/ )
Partilhar
Opções de suporte adicionais
Fóruns de Suporte da Comunidade Microsoft
Contacte-nos directamente
Encontre um parceiro certificado Microsoft
Loja Microsoft