2016-07-05 1 views
0

Voici la manière dont je peux afficher la chaîne "dcba":Pourquoi je peux inverser une chaîne en transmettant une variable sans passer une vraie chaîne? (Code simple)

main() 
{ 
    char s[10] = "abcd"; 
    puts(strrev(s)); 
} 

La façon dont je reçois un "Segmentation Fault" (pourquoi?):

puts(strrev("abcd")); 

Et ici est la fonction qui inverse la chaîne:

char *strrev(char *s) 
{ 
    int i, j; 
    char aux; 

    for(i=0, j=strlen(s)-1; i<j; i++, j--) 
    { 
     aux = s[j]; 
     s[j] = s[i]; 
     s[i] = aux; 
    } 

    return s; 
} 
+0

Un littéral de chaîne est constant. – limits

+1

Attention, @overtheboard. Bien qu'il soit sage de traiter les littéraux comme s'ils étaient constants, ce mot a une signification spécifique dans la norme. Ils ne sont pas * requis * pour être immuables et, en fait, la phase 6 crée un tableau de 'char' plutôt que' const char'. Je suis sûr que vous vouliez dire le premier mais je me sens mal à l'aise pédant aujourd'hui :-) – paxdiablo

+0

Ce code fonctionne pour moi .. – Twinkle

Répondre

4

En C, il est parce que d'essayer de modifier une chaîne littérale est l'une des choses qui est considéré comme un comportement non défini. La raison pour laquelle la modification de chaîne littérale a été marquée comme comportement indéfini dans la norme C originale (en gardant à l'esprit que l'intention originale des organismes de normalisation ANSI/ISO C était de codifier la pratique existante plutôt que d'inventer un nouveau langage). implémentations existant à l'époque stocké des littéraux de chaîne dans la mémoire morte, ou partagé des littéraux de chaîne identiques pour réduire l'utilisation de la mémoire.

Et, puisque chaque itération de la norme après ce point la compatibilité descendante d'une valeur (et certaines implémentations peuvent encore pour optimiser l'espace ou de protéger les chaînes littérales de la corruption par inadvertance), il n'y a pas eu de réelle volonté de le changer.

La ligne de fond, un comportement indéfini est généralement mauvaise, ne le faites pas.

+0

AFAIK, pas seulement pré-normes. C'est encore fait de cette façon ces jours-ci. –

+0

@Rudy, excuses, je ne voulais pas suggérer que ce n'était pas fait de cette façon aujourd'hui, juste parce que c'était fait avant C89/90, ils devaient l'honorer. Je vais essayer de changer la réponse pour clarifier. – paxdiablo

+0

pas besoin de s'excuser. Mais les littéraux sont souvent encore en mémoire. D'où le segfault. –