85 votes

char* vs std::string en c++

Quand dois-je utiliser std::string et quand dois-je utiliser char* pour gérer des tableaux de char en C++ ?

Il semble que vous devriez utiliser char* si la performance (vitesse) est cruciale et que vous êtes prêt à accepter un certain risque en raison de la gestion de la mémoire.

Y a-t-il d'autres scénarios à envisager ?

58voto

Gal Goldman Points 2563

Mon point de vue est le suivant :

  • N'utilisez jamais de char * si vous n'appelez pas du code "C".
  • Utilisez toujours std::string : C'est plus facile, c'est plus convivial, c'est optimisé, c'est standard, cela vous évitera d'avoir des bogues, cela a été vérifié et il a été prouvé que cela fonctionnait.

57voto

Skurmedel Points 9227

Vous pouvez passer std::string par référence s'ils sont grands pour éviter la copie, ou un pointeur sur l'instance, donc je ne vois pas de réel avantage à utiliser char des pointeurs.

J'utilise std::string / wstring pour plus ou moins tout ce qui est du texte réel. char * est utile pour d'autres types de données et vous pouvez être sûr qu'elles sont désallouées comme il se doit. Dans le cas contraire std::vector<char> est la voie à suivre.

Il y a probablement des exceptions à tout cela.

14voto

Suma Points 11966

Utilisation de la chaîne brute

Oui, il est parfois possible de le faire. Lorsque vous utilisez des const char *, des tableaux de chars alloués sur la pile et des chaînes de caractères littérales, vous pouvez le faire de manière à ce qu'il n'y ait pas d'allocation de mémoire du tout.

L'écriture d'un tel code demande souvent plus de réflexion et de soin que l'utilisation d'une chaîne de caractères ou d'un vecteur, mais avec des techniques appropriées, c'est possible. Avec des techniques appropriées, le code peut être sûr, mais vous devez toujours vous assurer que lorsque vous copiez dans char [], vous avez des garanties sur la longueur de la chaîne copiée, ou vous vérifiez et gérez les chaînes surdimensionnées de manière élégante. Ne pas le faire est ce qui a donné à la famille de fonctions strcpy la réputation d'être peu sûre.

Comment les modèles peuvent aider à rédiger des tampons de caractères sûrs

En ce qui concerne la sécurité des tampons char [], les modèles peuvent aider, car ils peuvent créer une encapsulation pour gérer la taille du tampon à votre place. Des modèles de ce type sont mis en œuvre, par exemple, par Microsoft pour fournir des remplacements sûrs à strcpy. L'exemple ici est extrait de mon propre code, le vrai code a beaucoup plus de méthodes, mais cela devrait être suffisant pour transmettre l'idée de base :

template <int Size>
class BString
{
  char _data[Size];

  public:
  BString()
  {
    _data[0]=0;
    // note: last character will always stay zero
    // if not, overflow occurred
    // all constructors should contain last element initialization
    // so that it can be verified during destruction
    _data[Size-1]=0;
  }
  const BString &operator = (const char *src)
  {
    strncpy(_data,src,Size-1);
    return *this;
  }

  operator const char *() const {return _data;}
};

//! overloads that make conversion of C code easier 
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
  return dst = src;
}

9voto

thesamet Points 2480

Une occasion à ne pas manquer char* et non std::string c'est lorsque vous avez besoin de constantes statiques de type chaîne de caractères. La raison en est que vous n'avez aucun contrôle sur l'ordre dans lequel les modules initialisent leurs variables statiques, et qu'un autre objet global d'un module différent peut faire référence à votre chaîne avant qu'elle ne soit initialisée. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std::string pour les pros :

  • gère la mémoire pour vous (la chaîne peut grandir, et l'implémentation vous allouera un tampon plus grand)
  • Interface de programmation de haut niveau, fonctionnant bien avec le reste de STL.

std::string cons : - deux instances distinctes de chaînes STL ne peuvent pas partager le même tampon sous-jacent. Ainsi, si vous passez par une valeur, vous obtenez toujours une nouvelle copie. - il y a une certaine pénalité de performance, mais je dirais qu'à moins que vos besoins soient spéciaux, elle est négligeable.

8voto

Jérôme Points 1150

Vous devriez envisager d'utiliser char* dans les cas suivants :

  • Ce tableau sera passé en paramètre.
  • Vous connaissez à l'avance la taille maximale de votre tableau (vous la connaissez OU vous l'imposez).
  • Vous ne ferez aucune transformation sur ce tableau.

En fait, en C++, char* sont souvent utilisés pour des petits mots fixes, comme des options, des noms de fichiers, etc...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X