Pourquoi préférez-vous char* au lieu de string, en C++?
Je suis un programmeur C en essayant d'écrire du code c++. J'ai entendu string
en C++ est mieux que char*
en termes de sécurité, de performance, etc, mais parfois, il semble que char*
est un meilleur choix. Quelqu'un a suggéré que les programmeurs ne doivent pas utiliser char*
en C++, car nous avons pu faire toutes les choses que char*
pourrait le faire avec de la ficelle, et c'est plus sécurisé et plus rapide.
Avez-vous déjà utilisé char*
en C++? Quelles sont les conditions?
OriginalL'auteur Jichao | 2009-11-19
Vous devez vous connecter pour publier un commentaire.
Il est plus sûr d'utiliser
std::string
parce que vous n'avez pas besoin de vous soucier de l'allocation /désallocation de la mémoire pour la chaîne. Le C++std::string
classe est susceptible d'utiliser unchar*
tableau en interne. Cependant, la classe va gérer l'allocation, l'allocation et la désallocation de la batterie interne pour vous. Cette opération supprime tous les risques habituels qui viennent avec l'aide de matières pointeurs, tels que des fuites de mémoire, les dépassements de tampon, etc.En outre, il est également très pratique. Vous pouvez copier des chaînes de caractères, ajouter à une chaîne de caractères, etc., sans avoir à fournir manuellement espace tampon ou d'utiliser des fonctions telles que la fonction strcpy/strcat. Avec std::string, c'est aussi simple que l'utilisation de la
=
ou+
opérateurs.En gros, c'est:
contre...
Edit:
En réponse à votre modifier au sujet de l'utilisation de
char*
en C++: de Nombreux programmeurs C++ sera demande, vous devriez jamais utilisationchar*
sauf si vous travaillez avec certains API/legacy fonction qui exige, dans ce cas vous pouvez utiliser lestd::string::c_str()
fonction pour convertir unstd::string
àconst char*
.Je dirais, cependant, il ya quelques utilisations légitimes de C-tableaux en C++. Par exemple, si la performance est absolument essentiel, un petit C-tableau sur la pile peut être une meilleure solution que
std::string
. Vous pouvez également écrire un programme où vous avez besoin d'un contrôle absolu sur allocation/libération de mémoire, dans lequel cas, vous devrez utiliserchar*
. Aussi, comme il a été souligné dans la section des commentaires,std::string
n'est pas garanti pour vous fournir un contigus, en écriture de la mémoire tampon *, de sorte que vous ne pouvez pas écrire directement à partir d'un fichier dans unstd::string
si vous avez besoin de votre programme pour être complètement portable. Toutefois, dans le cas où vous avez besoin pour ce faire,std::vector
serait encore probablement préférable à l'utilisation du raw C-tableau.* Bien qu'en C++11 ce qui a changé, de sorte que
std::string
ne vous fournir une mémoire tampon contiguëstd::string::c_str()
) plutôt trivial.Que std::string rend difficile à impossible d'obtenir une écriture de la mémoire tampon est un problème---vous devez compter sur les détails d'implémentation (la question est interprétée de deux manières à la fois sur l'adéquation de la norme l'exige &s[0] à travailler comme il le fait pour les vecteurs), ou de les mélanger dans un autre récipient (vecteurs ou des tableaux de char) avec des chaînes.
Une raison simple à utiliser char* au lieu de string est si vous devez éviter l'allocation dynamique de la mémoire (c'est à dire peut-être dans un gestionnaire d'interruption ou sur un système embarqué).
Je pense que toutes les exceptions descendre, l'utilisation, char* si vous savez que vous devez. Si vous n'avez pas une bonne raison (et la plupart du temps vous n'avez pas), utiliser std::string.
Une autre instance spécifique à préférer char* plus de std::string est l'endroit où vous avez besoin d'une chaîne statique constante. Si vous avez static std::string cas (dans un fichier cpp ou que les membres de classe statiques) ensuite, vous pouvez exécuter dans l'ordre d'initialisation des problèmes. À l'aide d'un raw char* permet d'éviter ce problème.
OriginalL'auteur Charles Salvia
Ok, la question beaucoup changé depuis que j'ai répondu.
Natif des tableaux de char sont un cauchemar de la gestion de la mémoire et des dépassements de mémoire tampon par rapport à std::string. Je préfère toujours utiliser std::string.
Cela dit, char tableau peut être un meilleur choix dans certaines circonstances, en raison des contraintes de performance (bien que std::string peut effectivement être plus rapide dans certains cas, mesurez d'abord!) ou l'interdiction de la dynamique de l'utilisation de la mémoire dans un environnement embarqué, etc.
OriginalL'auteur Fred Larson
En général, std::string est plus propre, plus sûr chemin à parcourir, car elle élimine le fardeau de la gestion de la mémoire du programmeur. La principale raison pour laquelle cela peut être plus rapide que char *s, c'est que std::string magasins de la longueur de la chaîne. Donc, vous n'avez pas à faire le travail d'une itération à travers l'ensemble du tableau de caractères à la recherche pour le caractère de fin NULL chaque fois que vous voulez faire une copie, append, etc.
Cela étant dit, vous pourrez toujours trouver beaucoup de programmes c++ qui utilisent un mélange de std::string et char *, ou même ont écrit leur propre chaîne de classes à partir de zéro. Dans les anciens compilateurs, std::string est un dévoreur de mémoire et pas forcément aussi rapide qu'elle pourrait être. Ce qui a cesse de s'améliorer au fil du temps, mais certaines des applications de haute performance (par exemple, les jeux et les serveurs) peuvent encore bénéficier de la main-écoute les manipulations de chaînes et de gestion de la mémoire.
Je recommande de commencer avec std::string, ou, éventuellement, la création d'un wrapper pour plus de fonctions utilitaires (par exemple, starts_with(), split(), le format(), etc.). Si vous trouvez lors de l'évaluation de votre code de manipulation de chaîne est un goulot d'étranglement, ou utilise trop de mémoire, vous pouvez alors décider si vous souhaitez accepter les risques supplémentaires et test d'une chaîne personnalisée de la bibliothèque de la demande.
CONSEIL: Une façon de contourner les problèmes de mémoire et d'utiliser std::string est d'utiliser une base de données incorporée comme SQLite. Ceci est particulièrement utile lors de la génération et la manipulation de très grandes listes de chaînes de caractères, et la performance est meilleure que ce à quoi vous pourriez vous attendre.
OriginalL'auteur kgriffs
C char * chaînes de caractères ne peut pas contenir de caractères '\0'. Chaîne C++ peut gérer des caractères null sans problème. Si les utilisateurs d'entrer des chaînes contenant des \0 et que vous utilisez des chaînes C, votre code peut échouer. Il y a aussi des problèmes de sécurité associés à cette.
Plus correctement, la chaîne C fonctions (strcpy, etc.) ne peut pas gérer le '\0', car ils l'utilisent comme une fin de chaîne de marqueur. Si vous êtes prêt à écrire vos propres fonctions, char* peut contenir le caractère '\0' just fine.
Je n'ai jamais vu quelqu'un utilise le caractère
'\0'
C char chaînes sont juste des pointeurs vers la mémoire brute. Comme pour le caractère '\0' j'ai vu qu'il est utilisé dans le cas où vous avez plusieurs chaîne de caractères dans une zone de la mémoire. à la fin de l'multiples cordes avec deux '\0'. La raison est qu'il permet d'économiser de la mémoire par rapport à une liste de plusieurs pointeurs. Ce qui est dit, est rare d'en voir.
OriginalL'auteur Mark Byers
Implémentations de
std::string
masquer l'utilisation de la mémoire de vous. Si vous écrivez des critiques des performances de code, ou en fait, vous avez à vous soucier de la fragmentation de la mémoire, puis à l'aide char* peut vous faire économiser beaucoup de maux de tête.Pour quoi que ce soit d'autre, est le fait que
std::string
cache tout cela vous rend beaucoup plus utilisable.OriginalL'auteur tsalter
Chaîne peut effectivement être mieux en termes de performances. Et d'innombrables autres raisons de sécurité, la gestion de la mémoire, de la pratique des fonctions de chaîne, faire std::string un choix infiniment mieux.
Edit: Pour voir pourquoi chaîne pourrait être plus efficace, lire Herb Sutter livres - qu'il traite d'une façon interne à mettre en œuvre la chaîne à utiliser l'Initialisation tardive combiné avec le Référencement.
Je pense qu'il parle de Copie sur Écriture de la sémantique, qui est en fait une mauvaise idée de ces jours en raison de multi-threading.
Si vous faites référence à copy-on-write, puis le temps a prouvé la valeur et à la fin il semble que copie sur écriture ne va pas améliorer les performances de surintensité début des implémentations de copie. Copy-on-write a beaucoup de problèmes avec le multithreading et les solutions exigent des verrous exclusifs qui ont plus de frais que le gain qui copie sur écriture fournit.
Certaines choses qui sont plus efficaces: l'obtention de la taille d'une chaîne de caractères est une constante de temps de fonctionnement en std::string, mais le temps linéaire sur la taille de la chaîne avec const char*, et de celle-ci une opération qui requiert le calcul de la taille de la chaîne
Dribeas, Caspin - est copie à l'écriture de la sémantique, je faisait allusion, et je vois votre point de vue (même si je vais devoir peser le pour et le contre). Merci.
OriginalL'auteur Fox
Utilisation
std::string
pour son incroyable confort - automatique de gestion de la mémoire et des méthodes /opérateurs. Avec quelques manipulations de chaînes, la plupart des implémentations ont optimisations en place (comme le retard de l'évaluation de plusieurs manipulations - économise de la mémoire de la copie).Si vous avez besoin de s'appuyer sur le char de mise en page dans la mémoire pour d'autres optimisations, essayez
std::vector<char>
à la place. Si vous avez un non-vide de vecteurvec
, vous pouvez obtenir unchar*
pointeur à l'aide de&vec[0]
(le vecteur doit être non vide).OriginalL'auteur orip
Réponse courte, je n'ai pas. L'exception, c'est quand je suis en utilisant des bibliothèques tierces qui en ont besoin. Dans ces cas, j'essaie de coller à std::string::c_str().
OriginalL'auteur larsmoa
Dans toute ma carrière professionnelle, j'ai eu l'occasion d'utiliser std::string à seulement deux projets. Tous les autres avaient leur propre chaîne de classes 🙂
Après avoir dit que, pour le nouveau code je l'utilise std::string quand je le peux, sauf pour le module limites (les fonctions exportées par la dll/bibliothèques partagées) où j'ai tendance à exposer interface C et rester à l'écart de types C++ et les enjeux de la binaire incompatibilités entre les compilateurs et les mst bibliothèque implémentations.
OriginalL'auteur Nemanja Trifunovic
De comparer et de contraste à la suite de C et de C++ exemples:
contre
OriginalL'auteur Pod
std::string est presque toujours préférable. Même pour la vitesse, il utilise le petit tableau sur la pile avant d'allouer dynamiquement de plus pour les grandes chaînes.
Cependant, char* pointeurs sont encore nécessaires dans de nombreuses situations pour écrire des chaînes de caractères/de données dans une crue de la mémoire tampon (par exemple, réseau I/O), qui ne peut être fait avec des std::string.
std::string
à l'aide de petits tableaux sur la pile n'est pas nécessairement vrai. C'est juste un détail d'implémentation qui les développeurs peuvent l'utiliser, pas un avantage inhérent à std::stringOriginalL'auteur Inverse
La seule fois où je l'ai récemment utilisé un style C chaîne de char dans un programme C++ est un projet qui, nécessaire à l'utilisation de deux bibliothèques C que (bien sûr) utilisé C chaînes exclusivement. La conversion d'avant en arrière entre les deux types de chaînes de fait le code vraiment compliquée.
J'ai également eu à faire des manipulations sur les chaînes qui est assez difficile à faire avec std::string, mais je n'aurais pas considéré comme une bonne raison d'utiliser les chaînes C en l'absence de la contrainte ci-dessus.
OriginalL'auteur ceo