Dans l'un de mes programmes, je dois m'interfacer avec du code hérité qui fonctionne avec const char*
.
Disons que j'ai une structure qui ressemble à:
struct Foo
{
const char* server;
const char* name;
};
Mon application de niveau supérieur ne traite que std::string
, j'ai donc pensé à l'utiliser std::string::c_str()
pour récupérer des const char*
pointeurs.
Mais quelle est la durée de vie c_str()
?
Puis-je faire quelque chose comme ça sans faire face à un comportement indéfini?
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
Ou suis-je censé copier immédiatement le résultat de c_str()
vers un autre endroit?
Je vous remercie.
.c_str()
. Je ne comprenais pas pourquoi parfois je n'obtiens que des parties de la chaîne, jusqu'à ce que je comprenne que leconst char*
ne vit pas éternellement, mais jusqu'à ce que la chaîne soit détruiteRéponses:
Le
c_str()
résultat devient invalide si lestd::string
est détruit ou si une fonction membre non-const de la chaîne est appelée. Donc, généralement, vous voudrez en faire une copie si vous avez besoin de le conserver.Dans le cas de votre exemple, il semble que les résultats de
c_str()
sont utilisés en toute sécurité, car les chaînes ne sont pas modifiées dans cette portée. (Cependant, nous ne savons pas ce que fontuse_foo()
ou~Foo()
pourraient faire avec ces valeurs; s'ils copient les chaînes ailleurs, alors ils devraient faire une copie conforme , et pas seulement copier leschar
pointeurs.)la source
non-const member function of the string is called.
?const
mot - clé. Une telle fonction peut faire muter le contenu de la chaîne, auquel cas la chaîne peut avoir besoin de réallouer la mémoire pour la version terminée par un nul de la chaîne renvoyée parc_str()
. Par exemple,size()
etlength()
sontconst
, afin que vous puissiez les appeler sans vous soucier de la modification de la chaîne, mais ceclear()
n'est pas le casconst
.Techniquement, votre code est correct.
MAIS vous avez écrit de telle manière qu'il est facile de casser pour quelqu'un qui ne connaît pas le code. Pour c_str (), la seule utilisation sûre est lorsque vous le passez en paramètre à une fonction. Sinon, vous vous exposez à des problèmes de maintenance.
Exemple 1:
Donc, pour la maintenance, rendez-le évident:
Meilleure solution:
Mais si vous avez des chaînes const, vous n'en avez pas réellement besoin:
D'ACCORD. Pour une raison quelconque, vous les voulez sous forme de chaînes:
pourquoi ne pas les utiliser uniquement dans l'appel:
la source
Il est valide jusqu'à ce que l'un des événements suivants se produise à l'
string
objet correspondant :Vous êtes d'accord avec votre code à moins que vous ne modifiiez ces
string
objets après lac_str()
copie de sfoo
mais avant l'use_foo()
appel.la source
La valeur de retour de c_str () n'est valide que jusqu'au prochain appel d'une fonction membre non constante pour la même chaîne
la source
Le
const char*
retour dec_str()
n'est valide que jusqu'au prochain appel non const à l'std::string
objet. Dans ce cas, tout va bien car vous êtesstd::string
toujours dans la portée deFoo
et vous ne faites aucune autre opération qui changerait la chaîne lors de l'utilisation de foo.la source
Tant que la chaîne n'est pas détruite ou modifiée, utiliser c_str () est OK. Si la chaîne est modifiée à l'aide d'un c_str () précédemment renvoyé, l'implémentation est définie.
la source
Pour être complet, voici une référence et une citation de cppreference.com :
la source