2011-01-26 7 views
1

ce code est-il correct?Copie de const char * en utilisant le constructeur std :: string

void SomeClass :: foo(const char * _name) { 
    //name is of type const char * 
    name = std::string(_name).c_str(); 
} 

on dirait qu'il fonctionne, mais iam ne sais pas si elle est ok

dois-je faire un vieux strcpy scolaire?

+2

WTF o_O. Vous lui passez un 'const char *', en convertissant en 'std :: string' et en retour en' const char * '??? Que diable pour? – mingos

+0

@mingos: Je soupçonne que l'OP a posé la question en raison d'une incertitude sur la portée et la durée de vie des choses temporaires, pensant que créer une chaîne et extraire le 'c_str()' pourrait faire la copie sans avoir à allouer explicitement des tampons et appelez strcpy. C'est une erreur parfaitement raisonnable - et commune - pour un programmeur C++ novice. –

+0

@Marcelo: OK, je n'ai pas pris en compte une telle possibilité :). – mingos

Répondre

6

C'est correct car il compile et ne provoque pas de comportement indéfini.

C'est et non ok puisque le nom pointe vers une mémoire non valide après l'exécution de l'instruction.

name = std::string(_name).c_str(); 

A la fin de cette déclaration, le std :: string temporaire est détruite et il libère la mémoire de c_str().

devrais-je faire une vieille école strcpy?

Non, il suffit de changer le nom d'être std :: string:

void SomeClass :: foo(const char * _name) { 
    //name is of type std::string 
    name = _name; 
} 
2

Si vous ne faites rien avec name, il est parfaitement sûr. Sinon, il échouera probablement à un moment donné dans le futur. Le pointeur de style C renvoyé par la fonction membre c_str() n'est valide que tant que le std::string temporaire existe (et tant que vous ne le mutez pas, ce que vous n'avez pas dans ce cas). Dès que la portée du bloc englobant se termine, le temporaire est détruit et toute utilisation de name vous place dans la zone crépusculaire. Comme d'autres l'ont suggéré, vous devez transformer name en std::string. Alternativement - si vous en avez vraiment besoin pour rester un char * - vous pouvez simplement écrire name = strdup(_name).

3

Ce n'est pas correct de l'utiliser par la suite - la mémoire peut être libérée dès que le temporaire disparaît. Pourquoi n'utilisez-vous pas une chaîne en tant que membre? Alors vous n'auriez pas à vous soucier de la gestion de la mémoire.

1

Dans ce cas, créez un objet temporaire et affectez-le à votre pointeur. Lorsque vous quittez la fonction, cet objet est détruit et votre pointeur pointe vers nulle part. Dans votre cas, cela peut fonctionner car la mémoire n'est pas encore écrasée. Mais vous devriez utiliser strcpy pour éviter ce problème.

+0

L'objet temporaire est détruit à la fin de l'expression complète et non à la fin de la fonction. –

0

Je vote pour strcpy. Pourquoi compliquer des choses simples?

Ou même mieux - puisque vous aurez évidemment besoin de l'utiliser plus tard, pourquoi ne pas le convertir en std::string et juste l'utiliser après, en oubliant tous ceux char *?

Questions connexes