2011-03-30 2 views
-1

Lorsque je compile et exécute mon code, j'obtiens une erreur de bus juste après l'impression de "démarrage". Voici ce qui se passe:Erreur de bus illogique de printf dans C

bash-3.2 $ ./remDup
à partir
Erreur de bus

#include <stdio.h> 
#include <string.h> 

void removeDups(char* str) 
{ 
    int len = strlen(str); 
    int i = 0; 

    for (i = 0; i < len; i++) { 
     char a = str[i]; 
     int k = i + 1; 
     int c = 0; 
     int j = 0; 

     for (j = k; j < len; j++) { 
      if (a != str[j]) { 
       str[k] = str[j]; 
       k++; 
      } else c++; 
     } 

     len -= c; 
    } 

    str[len] = '\0'; 
} 

int main(int argc, const char* argv[]) 
{ 
    char *str1 = "apple"; 

    printf("%s -> ", str1); 
    removeDups(str1); 
    printf("%s\n ", str1); 

    return 1; 
} 

Répondre

4

Si vous définissez une chaîne comme:

char *str1 = "apple"; 

vous n'êtes pas autorisé à modifier le contenu - la norme est tout à fait clair que ce comportement est indéfini (a). Utilisation:

char str1[] = "apple"; 

à la place et il vous donnera une copie modifiable. Il est fonctionnellement équivalent à:

char str1[6]; strcpy (str1, "apple"); 

(a) C99 6.4.5 "String literals", paragraphe 6 états:

Il est précisé si ces tableaux sont distincts à condition que leurs éléments ont les valeurs appropriées. Si le programme tente de modifier un tel tableau, le comportement n'est pas défini.

+0

wouah merci. :) mais pourquoi aurais-je une erreur de bus avant d'appeler removeDups? – gfrkwiz

+2

Vous ne le faites pas, le plantage est dans 'removeDups' - vous ne voyez pas votre sortie' "% s ->" 'printf parce qu'il n'y a pas de \ n - donc il ne reçoit pas débusqué avant l'accident. – GrahamS

4

vous modifiez les littéraux de chaîne qui résident souvent dans la mémoire en lecture seule. La norme indique également que tenter de modifier des littéraux est un comportement indéfini.

Lorsque vous utilisez des pointeurs vers des chaînes littérales, vous devez soit les déclarer comme const, const char * str="text"; ou sous forme de tableaux char str[] = "text";

Modification par exemple:

char str1[] = "apple"; 

Dans ce cas, le compilateur va créer un array sur stack, et copiez le littéral de chaîne en lecture seule dans celui-ci.