Pourquoi ne pas wstring :: c_str provoquer une fuite de mémoire si pas correctement supprimé
-
26-09-2019 - |
Question
segment de code 1:
wchar_t *aString()
{
wchar_t *str = new wchar[5];
wcscpy(str, "asdf\0");
return str;
}
wchar_t *value1 = aString();
segment de code 2
wstring wstr = L"a value";
wchar_t *value = wstr.c_str();
Si la valeur du segment de code 2 ne sont pas effacées alors une fuite de mémoire ne se produit pas. Cependant, si valeur1 du segment de code 1 ne sont pas supprimées il y a une fuite de mémoire. Le code interne à wstring :: c_str regarde la même chose pour moi.
La solution
Une règle importante:. Vous devez utiliser delete
sur tout ce qui a été créé par new
, et vous ne devez pas quoi que ce soit d'autre suppression
wstr.c_str()
renvoie un pointeur vers un tampon qui est géré par l'objet wstring
. Il sera désallouée lorsque la chaîne est détruite, après quoi le pointeur ne sera plus valide. L'utilisation delete
à ce sujet est faux. Le pointeur sera également invalidée si vous modifiez la chaîne.
aString()
renvoie un pointeur vers un tampon qui a été créée en utilisant new[]
, vous devez donc le supprimer lorsque vous avez terminé (à l'aide delete[]
, pour correspondre new[]
). Ceci est sujette aux erreurs, ce qui explique pourquoi il est préférable d'utiliser des classes de gestion des ressources (comme string
, wstring
, des conteneurs et des pointeurs intelligents) plutôt que de passer des pointeurs premières autour et en espérant qu'ils sont traités correctement.
Autres conseils
Parce que c_str()
vous renvoie un pointeur sur la représentation interne du wstring
. La classe conserve le contrôle des données qu'il contient.
Tiré du basic_string::c_str()
documentation de MSDN :
La chaîne de retour de style C ne devrait pas être modifié, car cela pourrait invalider le pointeur sur la chaîne, ou supprimé, que la chaîne a une durée de vie limitée et appartient à la chaîne de classe .
Je vais sortir sur un membre et dire qu'un wstring est pas un wchar_t, mais une classe qui a un opérateur de retourner un wchar_t *, donc dans le destructor de wstring, il libère probablement sa propre copie du wchar_t * il retourne.