2009-06-03 17 views
5

Nel codice qui sotto, la linea:Segmentation fault - char puntatore

*end = *front; 

dà un segmentation fault. Ho posto una domanda simile a here ma non sono sicuro che sia perché ho due copie di num. Si prega di spiegare perché è seg-faulting. Grazie.

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

char* getPalin(char* num); 

int main() 
{ 
    char* num = (char*)malloc(100); 

    num = "123456"; 

    printf("%s\n", getPalin(num)); 

    return 0; 
} 

char* getPalin(char* num) 
{ 
    int length = strlen(num); 

    if (length % 2 == 0) 
    { 
     char* front = num; 
     char* end = num + strlen(num) - 1; //pointer to end 

     while(front != num + (length/2)) //pointers not middle yet 
     { 
      *end = *front; 

      printf("%c", *end); 

      front++; 
      end--; 
     } 
    } 

    return num; 
} 

risposta

15

Queste due linee:

char* num = (char*)malloc(100); 
num = "123456"; 

hanno il seguente effetto.

Il primo alloca 100 byte e imposta num in modo che punti a quei byte.

Il secondo modifica num per puntare alla stringa "123456" che è quasi certamente in memoria di sola lettura.

Qualsiasi tentativo di modificare il contenuto della memoria di sola lettura comporterà una violazione della segmentazione. È necessario copiare la stringa nella malloc 'd num prima di tentare di cambiarlo, con:

strcpy (num, "123456"); 

Questa è la linea che si dovrebbe avere in cui attualmente si dispone:

num = "123456"; 
4

Usa

strncpy(num, "123456", 100); 

anziché

num = "123456"; 
+0

scusa, non sizeof (num), ma la dimensione della memoria allocata, ovvero 100. I. strncpy (num, "123456", 100); – Konstantin

+3

OP ha chiesto spiegazioni ma hai dato solo una soluzione. E non dimenticare di aggiungere manualmente null-terminator dopo strncpy perché non è garantito che strncpy lo aggiunga. So che non è rilevante in questo esempio perché "123456" è più corto di 100 byte ma se hai deciso di usare strncpy piuttosto che strcpy, usalo correttamente - hai evitato un potenziale problema (sovraccarico del buffer) ma ne hai introdotto uno (stringa non terminata) . – qrdl

+0

@qrdl - Finché la dimensione di destinazione specificata in strncpy è maggiore della lunghezza della stringa, strncpy eseguirà automaticamente il riempimento con caratteri nulli. È solo se la dimensione della destinazione è specificata come inferiore alla lunghezza della stringa da copiare che il terminatore null può essere perso. Un altro punto è ricordare che strncpy NON verificherà che ci sia spazio sufficiente nella memoria di destinazione. Quindi suppongo che strncpy (num, "123456", sizeof (num)) sia più corretto. – ChrisBD

1

Come per la risposta di Konstantin.

È già stata allocata memoria per num con l'istruzione malloc.

Se non avesse allora si potrebbe farla franca:

char* num = "123456"; 

che definisca e allocare memoria al volo ma sarebbe molto probabilmente essere assegnato come una costante e, quindi, di sola lettura.

L'utilizzo di strncpy anziché di strcpy per copiare "123456" garantisce che qualsiasi spazio aggiuntivo oltre la fine del terminatore nullo di stringa venga anche inizializzato su null, purché si specifichi n come 100 (per l'esempio). Altrimenti senza inizializzare la memoria allocata da malloc su null (memset (num, 0, 100)), allora è concepibile che si possa andare oltre la fine della stringa.

Oh quasi dimenticato. È consigliabile utilizzare strcpy_s o strncpy_s poiché sono più sicuri, anche se per il tuo codice non avrà importanza.

+0

In realtà considero queste due funzioni _s() come una stampella per le persone che non sanno come codificare in modo difensivo [cioè, prima verifica le precondizioni - Non ho mai nemmeno trovato la necessità di usare strncpy() e il mio codice è ancora come "sicuro" come qualsiasi che utilizza le varianti _s()]. Inoltre, non fanno ancora parte dello standard. – paxdiablo

+0

Di qui la ragione per cui l'ho detto opportuno. Non smette mai di stupirmi quanto il software commerciale si lascia aprire agli attacchi di sovraccarico del buffer. – ChrisBD

0

La ragione per l'errore è:

char* num = (char*)malloc(100); 

In questa linea si è dichiarato num come un puntatore a un array o puntatore al suo primo elemento non come una stringa.

num = "123456"; 

Questa riga è stata utilizzata num come l'hai dichiarata come una stringa.Questa è violazione della segmentazione e quindi del problema del segmento. Il preferibile (corretta) della sintassi per il codice è:

char num[100]; 
    strcpy(num,"123456"); //Even if you use num="123456"; here it would still be wrong 

O

char* num = (char*)malloc(100); 
    strcpy(num,"123456"); 

O

char num[100]={'1','2','3','4','5','6'}; 

Qualsiasi di questi sarebbe fare il vostro lavoro.

Problemi correlati