Pergunta

meus segfaults código e eu não sei porquê.

 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  }

O depurador gdb me diz, o problema está na linha 6, onde eu quero armazenar um char, em c-corda Isto é o que ele diz (se eu usar dereferencing ponteiro lvalue, é o mesmo problema.):

(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

Estou aprendendo com K & livro R-C e este é simplificada exemplo do capítulo 2.8 (a função remove). Eu não tenho nenhuma idéia de onde está o problema.

Foi útil?

Solução

porque char * s = "abcde"; cria corda na memória somente leitura. tente

char s[] = "abcde";

EDIT: Explicação:. Char * é ponteiro, e "ABCDE" é criado na memória somente leitura -> imutável

char [] é matriz, que é inteiramente armazenado em pilha e inicializado a partir da memória, de modo que é mutável

Outras dicas

Quando você define um ponteiro para a string literal , declará-lo como const char *.

const char *s = "abcde";

Dessa forma, seu compilador reclama quando você tenta enviar essa string para a função de substituição ().

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

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

Não discordando, mas apenas para elaborar: Considere o que aconteceria se o compilador permitido isso. Você poderia escrever:

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

Se o compilador reconhece que os dois literais são os mesmos e re-usos, mas, em seguida, também permite que a linha 3, a saída seria:

xbcde
xbcde

O que provavelmente não é o que você gostaria. Isto seria particularmente misteriosa se os dois literais foram em partes amplamente separadas do programa.

Experimente:

#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;
}

Meu palpite é a definição de parâmetros onde você define o tipo como uma matriz de caracteres. Enquanto você está passando um ponteiro para um char

Você pode tentar mudar a primeira linha para o seguinte:

 void overwrite(char *str, char x) {

Uma matriz de caracteres e um ponteiro de char não são semanticamente o mesmo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top