Segmentation Fault quando si scrive su una stringa

Sto provando a scrivere una funzione di inversione sul posto e ho seguito il codice online praticamente esattamente, ma il seguente programma esegue un errore di bus. Sto passando il tipo sbagliato di discussione per invertire ()?

void reverse(char *str) { char * end = str; char tmp; if (str) { while (*end) { ++end; } --end; while (str < end) { tmp = *str; *str++ = *end; *end-- = tmp; } } } int main() { char *s = "sample"; reverse(s); printf("%s\n"); return 1; } 

Per sapere cosa sta succedendo, devi capire il layout di memoria di un programma C.

 char *s = "sample"; // Here the "sample" string is placed in // the read only memory of the Initialized Data segment. 

Qui, non puoi modificare i dati. ” s ” è un puntatore a un char const (“sample”) e stai cercando di modificare il char const . Questo è il motivo per cui ricevi l’ bus error errore del bus error .

  |Stack frame of main() | |char *s | |-------------------------------| |Stack frame of reverse() | |char *end | |char tmp | | | |-------------------------------| | | | | | | | | | | |-------------------------------| | | | HEAP | | | |-------------------------------| | | | UNINITIALIZED DATA (BSS) | | | |-------------------------------| | | | INITIALIZED DATA | | | |"sample" | | | | | |(Read Only)| (Read/Write) | |-------------------------------| | Text or Code Segment | | | |-------------------------------| 

AGGIORNAMENTO Sotto il post non è correlato alla tua domanda. Ma se sai dove si trova la memoria allocata per tutte le variabili in C, allora puoi programmare meglio. Il seguente programma offre una migliore comprensione del layout di memoria di un programma C. Non ho incluso gli argomenti della riga di comando, l’argomento della funzione e i valori di ritorno della funzione nel diagramma. Le persone che desiderano aggiornare questo post possono aggiungere gli argomenti della riga di comando, l’argomento della funzione e i valori restituiti della funzione nel diagramma.

 |Stack frame of main() | |local_To_Main | | | #include  |-----------------------------------| #include  |Stack frame of function1() | int gVariable1 = 100; |local_To_Function1 | int gVariable2; |iptr | char cstring[10] = "Hello"; | \ STACK | char* cptr = "Hello World"; |------\---------------|------------| void function1(void) | \ \|/ | { | \ | static int j = 5; | \ | int local_To_Function1; | \ ^ | int *iptr; | \ | | iptr = (int *) malloc(sizeof(int)); |------------\---------------|------| free(iptr); | HEAP \ --- | } | \---> |int| | | --- | int main(void) |-----------------------------------| { | | static int i; | UNINITIALIZED DATA (BSS) | int local_To_Main; |gVariable2(initialized to 0) | |i (initialized to 0) | |-----------------------------------| function1(); | | return 0; | INITIALIZED DATA | } | | |"Hello World" |gVariable1 =100 | | ^ |cstring="Hello" | | | |j=5 | | |---< ---<---- cptr | |(Read Only) | (Read/Write) | |-----------------------------------| | Text or Code Segment | | | |-----------------------------------| 

Potresti voler cambiare

 char *s = "sample"; //Pointer to string literal 

a

 char s[] = "sample"; // mutable copy of string literal 

È un comportamento indefinito provare e modificare i letterali stringa, dovrebbero essere usati come const char * .


Probabilmente non correlato, ma un suggerimento,

Quando fai qualcosa come *end-- , potresti voler mettere la paranesia in modo che faccia ciò che pensi che faccia.

Quanto sopra può essere

 (*end)-- 

o

  *(end--) 

E hai bisogno di una buona conoscenza delle regole di precedenza per essere sicuro che quello che vuoi sia ciò che sta accadendo.

La tua funzione di inversione è perfettamente corretta. Solo alcune cose con la parte principale della funzione:

  • come diceva KarthikT, s dovrebbe essere char[] not char* perché la modifica letterale non è definita.

  • nella tua funzione printf, hai dimenticato di inserire s come parametro.

  • return 0 successo. return 1 è errore.

Quindi il nuovo main dovrebbe essere come:

 int main() { char s[] = "sample"; reverse(s); printf("%s\n", s); return 0; } 

Produzione:

 elpmas 
 char *str="sample"; 

Qui il campione viene archiviato nella memoria di sola lettura, quindi non è ansible apportare modifiche a tali valori letterali.

Per fare manipolazioni, devi memorizzare i letterali nella memoria di lettura-scrittura. Il codice sottostante può risolvere il tuo problema.

 #include void reverse(char *str) { char temp,*end; for(end=str;*end;end++); end--; for(;str 

Produzione:

 elpmas