2011-09-18 29 views
8

Sto provando a rovescio una stringa.Risoluzione dei problemi di errore bus

Questo è il codice ho provato:

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

int main(){ 
    char *c="I am a good boy"; 
    printf("\n The input string is : %s\n",c); 
    printf("\n The length of the string is : %d\n",strlen(c)); 
    int i,j; 
    char temp; 
    int len=strlen(c); 
    for(i=0,j=len-1;i<=j;i++,j--) 
    { 
      temp=c[i]; 
      c[i]=c[j]; 
      c[j]=temp; 
    //printf("%c\t%c\n",*(c+i),*(c+(len-i-1))); 
    } 
    printf("\n reversed string is : %s\n\n",c); 
} 

Il codice in uscita un Bus error : 10.

Ma se riscrivo lo stesso codice come:

int main(void) 
{ 
    char *str; 
    str="I am a good boy"; 
    int i,j; 
    char temp; 
    int len=strlen(str); 
    char *ptr=NULL; 
    ptr=malloc(sizeof(char)*(len)); 
    ptr=strcpy(ptr,str); 
    for (i=0, j=len-1; i<=j; i++, j--) 
    { 
     temp=ptr[i]; 
     ptr[i]=ptr[j]; 
     ptr[j]=temp; 
    } 
    printf("The reverse of the string is : %s\n",ptr); 
} 

Funziona perfettamente bene.

Perché il primo codice genera errori di bus o di segmentazione?

+1

perfavore riformattare il codice. –

+0

Ho provato a formattare il più possibile, ma davvero non so come farli allineare. – sethu

+1

Si prega di formattare il codice rielaborando il tutto con quattro spazi. – SLaks

risposta

16

L'errore di bus si verifica perché in molti (se non più o tutti i moderni) compilatori C, i valori letterali delle stringhe sono allocati nella memoria di sola lettura.

Stai invertendo la stringa in posizione. Nel tuo primo snippet di codice stai provando a scrivere in una stringa letterale. Non è una buona idea.

Nel secondo caso, hai malloc'd una stringa che lo ha messo sull'heap. Ora è sicuro invertire quella stringa sul posto.

ADDENDUM

Per il commentatore che ha chiesto circa segfaults contro errori del bus, che è una grande domanda. Ho visto entrambi. Ecco un errore di bus su un Mac:

$ cat bus.c 
char* s = "abc"; int main() {s[0]='d'; return 0;} 

$ gcc --version bus.c && ./a.out 
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659) 
Copyright (C) 2007 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Bus error 

Su altri sistemi operativi/compilatori si possono infatti ottenere un segfault.

+0

Ho pensato che provare a scrivere memoria di sola lettura avrebbe causato un segfault, non un errore di bus? O è specifico del sistema operativo? – cHao

+0

Ho visto entrambi! –

+0

Devi fare qualcosa di stravagante laggiù. :) Solo volta che ho mai visto un errore di bus, la scheda madre era pessima. – cHao

1

Gli array di caratteri specificati in "I am a good boy" sono in genere costanti - non è possibile modificarli. Ecco perché la prima variante si blocca. Il secondo no, mentre fai una copia dei dati e poi la modifichi.

6

Copiarlo sull'heap è un'opzione. Tuttavia, se si desidera solo di allocare un (stack) matrice locale, si può fare:

char str[] = "I am a good boy"; 

Poi, la stringa costante verrà copiato alla pila.

0

char * str = "Sono un bravo ragazzo"; Trattata come letterale e cercando di modificarla si tradurrà in errore del bus. È equivalente a const char * str = "I am a good boy", cioè puntatore a una stringa costante e cercando di modificare una stringa costante non è permesso.

MODIFICA: Nel momento in cui malloc() e copia si sta giocando con una copia della stringa originale e ptr non è di tipo 'const char *', invece è 'char * ptr' e non si lamenta.

0

compilazione con C++ (g ++) mostra deprecazione di assegnare una stringa letterale di un non-const char * che è progettato per impedire questo errore:

[email protected]:~/udlit_debug$ g++ ../buserr.cpp 
../buserr.cpp: In function ‘int main()’: 
../buserr.cpp:5:13: warning: deprecated conversion from string constant to ‘char*’ 
../buserr.cpp:7:61: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

L'avviso rilevante è sulla linea 5.

Cambiare la dichiarazione in const char * come indicato impedisce le assegnazioni nella stringa letterale.

Questa è anche una lezione sul perché non si dovrebbero ignorare gli avvisi.

Problemi correlati