Les autres réponses ont donné à la langue de l'avocat de réponses au sujet de ce que vous ne pouvez pas compter sur. Ceux qui sont du bon et du vrai, et je ne vais pas le répéter. Je vais donner une réponse sur la façon dont vous pouvez obtenir l'effet observé de manière sécurisée.
La solution est simple: il suffit d'insérer un appel à l' c_str()
:
std::string my_string = "";
char test = my_string.c_str()[0];
assert(test == 0);
ou plus directement:
const char* my_string = "";
char test = my_string[0];
assert(test == 0);
C'est sûr, parce que le C-style chaînes sont garantis d'être terminées par un zéro, de sorte que le pointeur résultant d'un c_str()
appel ou C-littéral de chaîne doit pointer vers un tableau d'au moins un octet. Pour une chaîne vide, qui sera toujours la résiliation de zéro octet.
Bien sûr, ce c_str()
truc est mauvais style à la valeur nominale. Cependant, il existe des situations où un tel accès de l'octet de fin permet d'éviter une partie de la manutention des cas spéciaux, ainsi, de réduire la complexité du code. Donc, il est certainement une option à considérer, de pesage de la laideur de l' c_str()
appel contre le code supplémentaire de la complexité explicitement la manipulation des chaînes vides.
Btw, c'est probablement aussi la raison pour laquelle vous l'avez remarqué que votre code ne plante pas: Votre std::string
mise en œuvre pour soutenir l' c_str()
de la fonction, et de la façon la plus simple de le faire est d'utiliser un zéro chaîne terminée dans le stockage interne (plus fin pointeur ou le nombre de caractères pour permettre à zéro octets à l'intérieur de cette chaîne). De cette façon, les deux fonctions begin()
et c_str()
renvoient un pointeur vers la mémoire interne.
Encore, ce n'est rien que vous pouvez compter sur, parce que la norme ne garantit pas que le comportement en aucune façon.