Domanda

il mio codice segfaults e non so perché.

 1  #include <stdio.h>
 2
 3  void overwrite(char str[], char x) {
 4    int i;
 5    for (i = 0; str[i] != '\0'; i++)
 6      str[i] = x;
 7  }
 8
 9  int main(void) {
10    char *s = "abcde";
11    char x = 'X';
12    overwrite(s, x);
13    printf("%s\n", s);
14    return 0;
15  }

Il debugger gdb mi dice che il problema si trova sulla riga 6, dove voglio archiviare un carattere, nella stringa c (se uso il dereferenziamento del puntatore al valore, è lo stesso problema). Questo è ciò che dice:

(gdb) run
Starting program: /tmp/x/x 

Breakpoint 1, overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:5
5         for (i = 0; str[i] != '\0'; i++)
(gdb) s
6           str[i] = x;
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x080483e3 in overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:6
6           str[i] = x;
(gdb) q

Sto imparando dal libro K & amp; R-C e questo è un esempio semplificato dal capitolo 2.8 (la funzione di rimozione). Non ho idea di dove sia il problema.

È stato utile?

Soluzione

perché char * s = " abcde " ;; crea una stringa nella memoria di sola lettura. prova

char s[] = "abcde";

EDIT: spiegazione: char * è puntatore e " abcde " viene creato nella memoria di sola lettura - > immutabili.

char [] è un array, che è interamente archiviato in pila e inizializzato dalla memoria, quindi è mutabile

Altri suggerimenti

Quando si definisce un puntatore a un valore letterale stringa , dichiararlo come const char * .

const char *s = "abcde";

In questo modo, il compilatore si lamenta quando si tenta di inviare quella stringa alla funzione overwrite ().

const char *s = "abcde";
char t[] = "fghij";
char x = 'X';

overwrite(s, x); /* oops */
overwrite(t, x); /* ok */

Non in disaccordo, ma solo da elaborare: considera cosa accadrebbe se il compilatore lo consentisse. Puoi scrivere:

char *s1="abcde";
char *s2="abcde";
s1[0]='x';
puts(s1);
puts(s2);

Se il compilatore riconosce che i due valori letterali sono uguali e li riutilizza, ma quindi consente anche la riga 3, l'output sarà:

xbcde
xbcde

Che probabilmente non è quello che vorresti. Ciò sarebbe particolarmente misterioso se i due letterali fossero in parti del programma ampiamente separate.

Prova:

#include <iostream>
#include <cstring>

using namespace std;

void overwrite(char[], char);

int main(void)
{
        char *s = strdup("abcde");
        char X = 'X';
        overwrite(s, X);
        cout << s << endl;

        if(s!=NULL)
                delete [] s;

        return 0;
}

void overwrite(char str[], char x)
{
        for(int i=0; str[i]!='\0'; i++)
                str[i] = x;
}

la mia ipotesi è la definizione del parametro in cui si definisce il tipo come una matrice di caratteri. Mentre passi un puntatore a un carattere

Potresti provare a cambiare la prima riga in questo:

 void overwrite(char *str, char x) {

Un array di caratteri e un puntatore a caratteri non sono semanticamente uguali.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top