Question

mon code segfaults et je ne sais pas pourquoi.

 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  }

Le débogueur gdb me dit que le problème se trouve sur la ligne 6, où je veux stocker un caractère, dans la chaîne de caractères (si j'utilise le déréférencement du pointeur lvalue, c'est le même problème.) C'est ce qu'il dit:

(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

Je tire des enseignements de K & amp R-C book et voici un exemple simplifié tiré du chapitre 2.8 (la fonction de suppression). Je ne sais pas où est le problème.

Était-ce utile?

La solution

car char * s = " abcde " ;; crée une chaîne dans la mémoire en lecture seule. essayer

char s[] = "abcde";

EDIT: explication: char * est un pointeur et "abcde" est créé dans la mémoire en lecture seule - > immuable.

char [] est un tableau qui est entièrement stocké sur la pile et initialisé à partir de la mémoire, de sorte qu'il est mutable

Autres conseils

Lorsque vous définissez un pointeur sur un littéral de chaîne , déclarez-le en tant que const char * .

const char *s = "abcde";

De cette manière, votre compilateur se plaint lorsque vous essayez d'envoyer cette chaîne à la fonction overwrite ().

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

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

Pas en désaccord, mais juste pour préciser: Pensez à ce qui se passerait si le compilateur le permettait. Vous pouvez écrire:

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

Si le compilateur reconnaît que les deux littéraux sont identiques et les réutilise, mais autorise également la ligne 3, votre sortie serait:

xbcde
xbcde

Ce qui n’est probablement pas ce que vous voudriez. Ce serait particulièrement mystérieux si les deux littéraux figuraient dans des parties du programme largement séparées.

Essayez:

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

Je suppose que c'est la définition du paramètre où vous définissez le type comme un tableau de caractères. Pendant que vous passez un pointeur sur un caractère

Vous pouvez essayer de changer la première ligne en ceci:

 void overwrite(char *str, char x) {

Un tableau de caractères et un pointeur de caractères ne sont pas sémantiquement identiques.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top