2010-04-29 4 views
7

Donc, je veux mieux comprendre comment fonctionnent les littéraux en C++. Je suis principalement concerné par les situations où vous assignez l'adresse d'une chaîne littérale à un pointeur, et passez-le. Par exemple:À quel point les littéraux de chaîne C++ sont-ils sûrs et fiables?

char* advice = "Don't stick your hands in the toaster."; 

Maintenant disons que je viens de passer cette chaîne autour en copiant des pointeurs pour la durée du programme. Bien sûr, ce n'est probablement pas une bonne idée, mais je suis curieux de savoir ce qui se passe réellement dans les coulisses.

Pour un autre exemple, disons que nous faisons une fonction qui renvoie une chaîne littérale:

char* foo() 
{ 
    // function does does stuff 
    return "Yikes!"; // somebody's feeble attempt at an error message 
} 

Maintenant, supposons que cette fonction est appelée très souvent, et la chaîne est utilisée seulement littérale environ la moitié du temps, il est appelé :

// situation #1: it's just randomly called without heed to the return value 
foo(); 

// situation #2: the returned string is kept and used for who knows how long 
char* retVal = foo(); 

Dans la première situation, que se passe-t-il réellement? La chaîne est-elle juste créée mais non utilisée, et jamais désaffectée?

Dans la deuxième situation, la chaîne va-t-elle être maintenue aussi longtemps que l'utilisateur en aura besoin? Que se passe-t-il quand ce n'est plus nécessaire ... cette mémoire sera-t-elle libérée (en supposant que rien ne pointe plus vers cet espace)? Ne vous méprenez pas, je ne prévois pas d'utiliser des littéraux de chaînes comme celui-ci. Je prévois d'utiliser un conteneur pour garder mes chaînes en échec (probablement std :: string). Je veux surtout savoir si ces situations pourraient causer des problèmes pour la gestion de la mémoire ou des données corrompues.

+8

Les littéraux de chaîne C++ sont parfaitement sûrs et fiables. Ce sont les programmeurs qui utilisent les littéraux de chaînes qui ne sont pas sûrs et fiables. –

+0

C'est ce que je pensais; J'avais juste besoin d'être rassuré, je suppose. Merci. :) –

Répondre

22

Les littéraux de chaîne ont le type const char[N] (où N est la longueur +1) et sont alloués statiquement. Vous n'avez pas besoin de vous soucier des problèmes de mémoire. Si une chaîne est utilisée dans votre programme, elle est gérée pour vous et se trouve quelque part dans la mémoire du programme (généralement en lecture seule).

C'est, ce sont « les mêmes »:

static const char str[] = "a string"; 
"a string" 

Lorsque vous pointez sur une chaîne littérale, vous pointez sur le premier caractère au tableau. En fait, parce que le type est const char[], il est seulement sûr de le pointer via const char*. La conversion du littéral de chaîne en char* est obsolète et peu sûre.

// the "same" 
static const char str[] = "a string"; 
const char* strPtr = str; // decays 

const char* s1 = "a string"; 
char* s2 = "a string"; // allowed, implicit const_cast 

*s1 = 'A'; // not allowed, it's const 
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior) 
+5

"La conversion de chaîne littérale à char * est obsolète et dangereuse." Ouais. A besoin de chaînes -fichier-si vous l'avez fait quelque part. Quoi qu'il en soit, ne faites pas ça. – Joshua

+1

Oui, merci d'expliquer l'aspect const en détail. Je savais qu'ils étaient constants, mais je me suis dit que je laisserais l'explication à quelqu'un qui les comprendrait mieux que moi. :) –

+2

Vous l'avez dit tout ce que je peux dire. –

1

Tout d'abord, déclarer la valeur de retour de foo comme const, parce que les chaînes littérales sont des constantes qui ne peuvent être changées sans que le « comportement non défini » redoutée. Cela forcera alors tous les pointeurs qui utilisent la valeur de retour de foo à être également déclarée const, et potentiellement limiter les dégâts qui peuvent être (involontairement) faits. Les littéraux de chaîne sont stockés dans la zone 'texte' d'un exécutable binaire - ils ne sont pas créés en tant que tels lors de l'exécution.

Questions connexes