Erreur de segmentation lors de la modification d'une chaîne à l'aide de pointeurs?
Contexte
Je suis en train d'apprendre le C, et je vais essayer d'inverser une chaîne de caractères à l'aide de pointeurs. (Je sais que vous pouvez utiliser un tableau; c'est plus sur l'apprentissage sur les pointeurs.)
Problème
Je reçois des défauts de segmentation lorsque vous essayez d'exécuter le code ci-dessous. GCC semble ne pas aimer la *end = *begin;
ligne. Pourquoi est-ce?
Surtout depuis que mon code est presque identique à le non-mal C de la fonction déjà discuté dans un autre question
#include <stdio.h>
#include <string.h>
void my_strrev(char* begin){
char temp;
char* end;
end = begin + strlen(begin) - 1;
while(end>begin){
temp = *end;
*end = *begin;
*begin = temp;
end--;
begin++;
}
}
main(){
char *string = "foobar";
my_strrev(string);
printf("%s", string);
}
source d'informationauteur brice
Vous devez vous connecter pour publier un commentaire.
Un problème, c'est le paramètre que vous passer à la fonction:
C'est une chaîne statique alloué à la lecture seule partie. Lorsque vous essayez de l'écraser avec
vous obtiendrez l'erreur de segmentation.
Essayer avec
et vous remarquerez une différence.
Le point clé est que dans le premier cas, la chaîne existe dans le segment en lecture seule et juste un pointeur est utilisé alors que dans le second cas, un tableau de caractères avec la bonne taille est réservé sur la pile et de la chaîne statique (qui existe toujours) est copié dans. Après que vous êtes libre de modifier le contenu du tableau.
Vous pouvez également utiliser le caractère nul de fin de chaîne afin d'échanger des personnages au sein d'une chaîne, évitant ainsi l'utilisation de tout l'espace supplémentaire. Voici le code:
Dans votre code, vous avez la suivante:
Il n'est que pure chance que cela fonctionne correctement (en fait, la raison est la priorité de l'opérateur). Il semble que vous ayez prévu au code de le faire réellement
Qui est entièrement faux. La façon dont vous l'avez, les opérations se passer comme
end
puis de déréférencement ilbegin
puis de déréférencement ilDans les deux cas, le déréférencement est superflu et doit être supprimé. Vous avez probablement prévu le comportement de la
Ce sont les choses que le lecteur d'un développeur batty parce qu'ils sont si difficiles à dépister.
Ce serait en place et en utilisant des pointeurs
Changement
char *string = "foobar";
àchar string[] = "foobar";
. Le problème est qu'unechar *
points de mémoire en lecture seule qui vous essayez ensuite de modifier provoque une erreur de segmentation.Ce qui rend pour une petite(ish) en fonction récursive et fonctionne en stockant les valeurs sur le chemin en bas de la pile et de l'incrémenter le pointeur au début de la chaîne (*s) sur le chemin du retour (return).
Intelligent à la recherche de code mais terrible en termes de l'utilisation des piles.
Voici ma version de la place C de la chaîne d'inversion.
Ci-dessous, vous pouvez voir mon code pour ce problème: