Liberando memória na pilha. Devo e como?
-
04-07-2019 - |
Pergunta
Estou escrevendo um Cesetup.dll para um aplicativo Windows Mobile. Deve ser não gerenciado, com o qual tenho pouca experiência. Portanto, não tenho certeza se devo libertar a memória que alocar e como faço.
Aqui está a função que escrevi:
Uninstall_Init(
HWND hwndParent,
LPCTSTR pszInstallDir
)
{
LPTSTR folderPath = new TCHAR[256];
_stprintf(folderPath, _T("%s\\cache"), pszInstallDir);
EmptyDirectory(folderPath);
RemoveDirectory(folderPath);
_stprintf(folderPath, _T("%s\\mobileadmin.dat"), pszInstallDir);
DeleteFile(folderPath);
// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE
// If you want to cancel installation,
// return codeUNINSTALL_INIT_CANCEL
return codeUNINSTALL_INIT_CONTINUE;
}
Pelo que entendi, a pasta é alocada na pilha. VazioDirectory () é minha própria função que remove todo o conteúdo do diretório. Removedirectory () e DeleteFile () são chamadas de sistema.
Minha pergunta é devo negociar folderPath
Antes da saída da função? Se eu deveria, como faço isso?
Solução
Eu acho que você quer usar isso:
delete [] folderPath;
Parece que você está alocando uma variedade de tchars, o que faz sentido, pois é uma corda. Quando você aloca uma matriz, você deve excluir usando o operador de exclusão da matriz (que você recebe, incluindo os colchetes na instrução Excluir). Tenho certeza de que você receberá um vazamento de memória com a solução da TREB.
Outras dicas
Há uma percepção errônea comum que eu já vi com pessoas que não estão utilizadas para a programação C/C ++ - quando vêem uma função com um parâmetro de ponteiro, eles acham que a variável deve ser alocada com novo. Não é esse o caso, uma variável local é adequada e preferida, pois você não precisa se preocupar com sua vida útil.
Você poderia simplificar sua vida tremendamente fazendo
TCHAR folderPath[256];
Minha solução preferida seria usar o STD :: String, mas eu coloquei isso em uma resposta separada.
Sim, você deve libertar a memória. Nenhuma das funções que você chama fará isso por você, e nem elas - não deveriam fazer sentido. A memória foi alocada com o novo operador do vetor e, portanto, deve ser libertado com o operador de exclusão do vetor, ou seja::
excluir [] pastaPath;
Geralmente, é melhor usar a STD :: String ou no seu caso Std :: Basic_String. Nesse caso, elimina um excesso de buffer em potencial quando seu caminho final é superior a 256 caracteres.
Uninstall_Init(
HWND hwndParent,
LPCTSTR pszInstallDir
)
{
std::basic_string<TCHAR> folderPath = pszInstallDir;
folderPath.append(_T("\\cache"));
EmptyDirectory(folderPath.c_str());
RemoveDirectory(folderPath.c_str());
folderPath = pszInstallDir;
folderPath.append(_T("\\mobileadmin.dat"));
DeleteFile(folderPath.c_str());
// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE
// If you want to cancel installation,
// return codeUNINSTALL_INIT_CANCEL
return codeUNINSTALL_INIT_CONTINUE;
}
Sim você deveria. Ligando
delete[] folderPath;
no final de sua função. Toda a memória atribuída com new
deve ser libertado com delete
.