Frage

mein Code segfaults und ich weiß nicht, warum.

 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  }

Der GDB-Debugger sagt mir, ist das Problem auf der Linie 6, wo ich ein Zeichen speichern möchten, in c-string (wenn ich lvalue Zeiger verwenden dereferencing, es ist das gleiche Problem.) Das ist, was er sagt:

(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

I von K & R-C Buch lerne und dieses Beispiel aus dem Kapitel vereinfacht 2.8 (die Entfernen-Funktion). Ich habe keine Ahnung, wo das Problem ist.

War es hilfreich?

Lösung

da char * s = "abcde"; schafft in Nur-Lese-Speicher-String. versuchen

char s[] = "abcde";

EDIT: Erklärung:. Char * ist Zeiger und "ABCDE" wird in Nur-Lese-Speicher erstellt -> unveränderlich

char [] ist array, die vollständig auf dem Stapel gespeichert und aus dem Speicher initialisiert, so Wandelbare

Andere Tipps

Wenn Sie einen Zeiger auf eine Stringliteral zu definieren, deklarieren es als const char *.

const char *s = "abcde";

Auf diese Weise Ihr Compiler beschwert sich, wenn Sie versuchen, diese Zeichenfolge an das Überschreiben () Funktion zu senden.

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

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

Nicht nicht zustimmen, aber nur zu erarbeiten: Überlegen Sie, was, wenn der Compiler erlaubt dies geschehen würde. Man könnte schreiben:

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

Wenn der Compiler erkennt, dass die beiden Literale gleich sind und wieder verwendet sie, aber dann können auch die Linie 3, die Ausgabe wäre:

xbcde
xbcde

Was ist wahrscheinlich nicht das, was Sie wollen. Dies wäre besonders geheimnisvoll sein, wenn die beiden Literale in sind weit voneinander getrennte Teile des Programms.

Versuchen Sie:

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

meine Vermutung ist, die Parameter Definition, wo Sie den Typ als ein Array von Zeichen definieren. Während Sie einen Zeiger auf ein char sind vorbei

Sie könnten versuchen, die erste Zeile auf diese Veränderung:

 void overwrite(char *str, char x) {

A char-Array und ein char Zeiger nicht semantisch gleich.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top