2013-08-14 2 views
0

Ce code est le noyau Linux utilise pour dépouiller espaces avant et après sur une chaîne:C bande de chaîne blancs renvoie une erreur de segmentation (core dumped)

char *strstrip(char *s) 
{ 
     size_t size; 
     char *end; 

     size = strlen(s); 

     if (!size) 
       return s; 

     end = s + size - 1; 
     while (end >= s && isspace(*end)) 
       end--; 
     *(end + 1) = '\0'; 

     while (*s && isspace(*s)) 
       s++; 

     return s; 
} 

Ici, j'utiliser comme tel:

int main(void){ 

    /* strip test*/ 
    char buffer2[60]; 
    char* testy2 = buffer2; 
    testy2 = "  THING!  "; 
    printf("The stripped string: \"%s\"\n",strstrip(testy2)); 
    return 0; 
} 

Le programme compile bien, mais lorsqu'il est exécuté, il déclare:

Segmentation fault (core dumped)

Pourquoi cela se passe-t-il?

Répondre

2
testy2 = "  THING!  "; 

définit testy2 pour pointer vers un littéral de chaîne. Cela peut exister dans la mémoire en lecture seule et ne peut donc pas être écrit par strstrip.

Vous devez soit allouer de la mémoire pour testy2

const char* s = "  THING!  "; 
testy2 = malloc(strlen(s)+1); 
strcpy(testy2, s); 
.... 
free(testy2); 

ou, plus facile, juste initialisez buffer2 avec la chaîne que vous souhaitez manipuler

char buffer2[] = "  THING!  "; 
printf("The stripped string: \"%s\"\n",strstrip(buffer2 
+0

Merci. Ça fonctionne maintenant. – turnt

2

Une chaîne dans votre code est généralement placé par le compilateur dans une section en lecture seule de l'espace mémoire de votre programme. Lorsque vous affectez testy2 = " THING! ";, vous définissez testy2 pour pointer vers un littéral de chaîne dans la mémoire statique "en lecture seule". Ensuite, lorsque vous appelez strstrip() pour modifier cette mémoire, vous obtenez un SIGSEGV, ou quel que soit votre plate-forme l'appelle, au point que strstrip() essaie d'écrire le caractère nul ('\0') car vous ne pouvez pas écrire dans la mémoire dont les attributs sont définis sur " lecture seulement". Pour obtenir une copie de ce littéral de chaîne que vous pouvez modifier, vous pouvez utiliser strcpy() pour en faire une copie et appeler le strstrip() sur cette copie. Bien sûr, pour en faire une copie, vous devez la copier dans la mémoire que vous possédez, que vous pouvez obtenir à partir de malloc(strlen(testy2)+1) ou new char[strlen(testy2)+1], ou comme vous l'avez fait dans votre message original, en créant une allocation locale. Une chose à noter est que strstrip() à la fois 1) renvoie un pointeur qui peut être différent du pointeur transmis, et 2) peut modifier la chaîne à la mémoire qui lui est transmise. Dans votre exemple, vous perdez le pointeur retourné parce que vous ne l'avez pas assigné à quelque chose ... ce qui n'est pas si grave car vous pouvez retrouver la même adresse en appelant simplement strstrip() sur le pointeur d'origine, mais ce serait un peu inefficace si vous aviez besoin de la corde dénudée plus d'une fois. Mais faites attention ici ... si vous avez utilisé malloc() ou new pour allouer dynamiquement de l'espace pour votre copie de la chaîne littérale (et assigné l'adresse retournée à un pointeur, disons testy2), alors n'attribuez pas le retour de strstrip() à ce pointeur, sinon vous ne pourrez plus utiliser le pointeur pour libérer la mémoire allouée dynamiquement! Lorsque vous appelez free() ou delete, vous devez lui passer le pointeur d'origine que vous avez obtenu de malloc() ou new, pas le pointeur que vous avez obtenu de strstrip().

3

Lors de l'affectation de testy2 (testy2 = " THING! ";), vous faites pointer sur statique lecture seule mémoire. Mais dans votre strstrip() vous essayez de le modifier.

Vous pouvez le résoudre en allouant dynamiquement à l'aide testy2malloc par exemple:

testy2 = malloc(sizeof("  THING!  ") + 1); 
strcpy(testy2, s); 

// But don't forget to free the memory at the end ! 
free(testy2); 
2

La ligne

testy2 = "  THING!  "; 

ne fait pas ce que vous pensez qu'il fait. Il ne copie pas " THING! " à buffer2. Il définit simplement le pointeur testy2 pour pointer vers une chaîne littérale " THING! ". Ensuite, lorsque vous appelez la fonction strstrip(), la fonction tente de modifier un littéral de chaîne, qui est un comportement indéfini. D'où la faute de segmentation.

Vous voulez probablement utiliser strcpy() au lieu de l'opérateur d'affectation:

strcpy (testy2, "  THING!  "); 
Questions connexes