2008-10-27 8 views
2

J'écris un CESetup.dll pour une application Windows Mobile. Il doit être non géré, avec lequel j'ai peu d'expérience. Donc, je ne suis pas sûr de savoir si je devrais libérer la mémoire que j'alloue et comment je le fais.Libérer de la mémoire sur le tas. Devrais-je et comment?

est ici la fonction que j'ai écrit:

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

Si je comprends bien, folderPath est alloué sur le tas. EmptyDirectory() est ma propre fonction qui supprime tout le contenu du répertoire. RemoveDirectory() et DeleteFile() sont des appels système.

Ma question est de savoir si je dois libérer folderPath avant que la fonction ne se termine? Si je devais, comment puis-je le faire?

Répondre

3

Je pense que vous voulez utiliser:

delete [] folderPath; 

Il semble que vous allouer un tableau de TCHARs, ce qui est logique puisque c'est une chaîne. Lorsque vous allouez un tableau, vous devez le supprimer à l'aide de l'opérateur de suppression de tableau (que vous obtenez en incluant les parenthèses dans l'instruction delete). Je suis sûr que vous aurez une fuite de mémoire avec la solution de Treb.

+0

Argh! Vous avez raison, bien sûr. Ma faute. – Treb

1

Oui, vous devriez. En appelant

delete[] folderPath; 

à la fin de votre fonction. Toute la mémoire affectée avec new doit être libérée avec delete.

4

Il y a une perception erronée commune que j'ai vu avec des gens qui ne sont pas habitués à la programmation C/C++ - lorsqu'ils voient une fonction avec un paramètre pointeur, ils pensent que la variable doit être affectée avec nouveau. Ce n'est pas le cas, une variable locale est appropriée et préférée, puisque vous n'avez pas à vous soucier de sa durée de vie.

Vous pouvez simplifier votre vie énormément en faisant

TCHAR folderPath[256]; 

Ma solution préférée serait d'utiliser std :: string, mais je l'ai mis que dans une réponse distincte.

+0

Vous avez absolument raison. Mais j'ai essayé ça et ça ne compilerait pas pour moi. – ageektrapped

+0

Je reçois des erreurs comme "DeleteFileW: impossible de convertir le paramètre 1 de 'LPTSTR [256]' en 'LPCWSTR'" – ageektrapped

+0

Aha - vous déclarez un tableau de LPTSTR, pas TCHAR. –

1

Oui, vous devriez libérer de la mémoire. Aucune des fonctions que vous appelez ne le fera pour vous, et elles ne devraient pas non plus - cela n'aurait aucun sens. La mémoire a été allouée avec le nouvel opérateur vectoriel et doit donc être libérée avec l'opérateur de suppression de vecteur, c'est-à-dire:

delete [] folderPath;

1

Il est généralement préférable d'utiliser std :: string, ou dans votre cas std :: basic_string. Dans ce cas, il élimine un débordement de tampon potentiel lorsque votre chemin final est supérieur à 256 caractères.

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; 
} 
+0

Est-ce que cela fonctionne sur les appareils Windows Mobile? Qu'est-ce que je dois inclure? – ageektrapped

+0

Je n'ai pas d'expérience directe avec Windows Mobile, mais cela fait partie de C++, pas du système d'exploitation. Vous devez # inclure . –

Questions connexes