Speicherzugriffsfehler in meinem RPG-Programm



  • Hallo Freunde der Sonne,

    Ich bin dabei ein kleines RPG zu schreiben. Der Code wird kompiliert, jedoch wird beim Ausführen ein Fehler ausgegeben:

    Speicherzugriffsfehler (Speicherabzug geschrieben)
    

    Leider war es mir durch die Unpräzisiertheit der Fehlermeldung nicht möglich, einen Codeabschnitt zu lokalisieren, der problematisch sein könnte.

    #include <stdio.h>
    
    // --- BEING CLASS ---
    
    // A being represents a Human or a living entity that can fight fight against other beings with the help of skills   
    
    struct Being 
    {
    	char name[20];
    	int life;
    	int mana;
    };
    
    void Being_init(struct Being* being, char name, int life, int mana)
    {
    	strcpy(being->name, name);
    	being->life = life;
    	being->mana = mana;
    }
    
    // i dont have to use pointer, but pointer is more efficient (processing time)
    void Being_print(struct Being* being)
    {
    	printf("Name: %s\n", being->name);
    	printf("Life: %d\n", being->life);
    	printf("Mana: %d\n", being->mana);
    }
    
    void Being_cast_fireball(struct Being* caster, struct Being* enemy)
    {
    	printf("Not implemented yet\n");
    }
    
    // --- MAIN PROGRAM ---
    
    int main()
    {
    	struct Being player;
    	Being_init(&player, "Player", 20, 5);
    	Being_print(&player);
    }
    

    Wo genau liegt der Fehler?

    Ich danke vom Herzen für alle Antworten!


  • Mod

    Ich sag's jetzt mal absichtlich nicht, denn dieser Fehler ist sehr einfach selber zu finden, aber du weißt offensichtlich nicht, wie man so etwas macht.

    1. Schritt: Schalt Compilerwarnungen ein! Alle. Immer. Und behandle Warnungen wie Fehler. Wenn du nicht weißt, wie man Compilerwarnungen einschaltet, dann versuch mal selber herauszufinden, wie man das macht.

    2. Schritt: Benutz einen Debugger! Dann lass das Programm einfach laufen und guck dir den Trace von der Stelle an, wo es gekracht hat. So findest du die unmittelbare Ursache des Fehlers. Falls dir das noch nicht reicht (in diesem Fall sollte es reichen), dann fang noch einmal von vorne an und nähere dich Schritt für Schritt der kritischen Stelle und guck stets nach, ob alles noch seine Richtigkeit hat. Wenn du nicht weißt, wie man einen Debugger benutzt, dann versuch mal selber herauszufinden, wie man das macht

    Schritt 1 wird in diesem Fall zum Erfolg führen, aber mach Schritt 2 auch einmal an diesem Beispiel, damit du lernst, wie es geht. Ist sehr wichtig, dass man das kann.



  • Vielen Dank, der Knackpunkt lag hier:

    In file included from main.c:2:0:
    /usr/include/string.h:125:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
     extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
    

    Ich habe die Zeile

    void Being_init(struct Being* being, char name, int life, int mana)
    

    wie folgt geändert:

    void Being_init(struct Being* being, char name[], int life, int mana)
    

    Also eine Liste, nicht ein einzelnes Zeichen übergeben, wodurch das Programm nun einwandfrei funktioniert.

    Bringe einem Menschen bei wie man fischt und er kann sich ein Leben lang ernähren, oder wie ging das nochmal? 😃
    Auf jeden Fall danke!



  • Dexter1997 schrieb:

    Also eine Liste, nicht ein einzelnes Zeichen übergeben, wodurch das Programm nun einwandfrei funktioniert.

    du übergibst da aber eine adresse bzw. eine referenz auf einen c-string (oder auf ein feld) und keine liste 🙄



  • und wenn man eine liste (ein char-array) übergeben wollte, wie müsste man das tun?


  • Mod

    Dexter1997 schrieb:

    und wenn man eine liste (ein char-array) übergeben wollte, wie müsste man das tun?

    Lass dich nicht verwirren, du machst alles richtig. Wade1234 hängt sich bloß an den Feinheiten von Arrays als Funktionsparametern auf. Wenn man in C ein Array an eine Funktion übergibt, dann wird nicht das Array in die Funktion kopiert, sondern ein Verweis auf das übergebene Array.

    Guck mal: https://ideone.com/JqEVsv

    Was du folglich noch verbessern könntest, ist const char name[] , da du keine Veränderungen an dem übergebenen Feld vornimmst, sondern nur eine Kopie des Inhalts erstellst.



  • SeppJ schrieb:

    [...] const char name[] [...]

    Wie ist es eigentlich sprachgeschichtlich dazu gekommen, daß soetwas hässliches in Parameterlisten überhaupt gültig ist? War soetwas auch in K&R-Style C schon erlaubt, eg:

    void foo(name)
    char name[];
    {}
    

    ?



  • Swordfish schrieb:

    War soetwas auch in K&R-Style C schon erlaubt, eg:

    void foo(name)
    char name[];
    {}
    

    ?

    Eher nicht, da

    Wikipedia: Varianten der Programmiersprache C schrieb:

    Neuerungen von C90
    ...
    - void für leere Funktionsparameter-Deklarationen und zur Kennzeichnung von Funktionen ohne Returnwert sowie void* für einen universell kompatiblen Zeigertyp kamen neu hinzu.
    - Die neuen Schlüsselwörter const, volatile und signed wurden eingeführt.
    ...



  • Dexter1997 schrieb:

    und wenn man eine liste (ein char-array) übergeben wollte, wie müsste man das tun?

    es ging einfach darum, dass eine liste eigentlich etwas völlig anderes ist, als das, was du da hast und dass man bei dem wort liste idr an sowas denkt: https://de.wikipedia.org/wiki/Liste_(Datenstruktur)

    also nur so für zukünftige unterhaltungen 😉



  • DirkB schrieb:

    Swordfish schrieb:

    [...]

    Eher nicht, da [...]

    wtf?



  • Wade1234 schrieb:

    Dexter1997 schrieb:

    und wenn man eine liste (ein char-array) übergeben wollte, wie müsste man das tun?

    es ging einfach darum, dass eine liste eigentlich etwas völlig anderes ist, als das, was du da hast und dass man bei dem wort liste idr an sowas denkt: https://de.wikipedia.org/wiki/Liste_(Datenstruktur)

    also nur so für zukünftige unterhaltungen 😉

    Und was wäre ein deutsches Wort für Array, das unmißverständlich ist, oder gibt es da keinen deutschen begriff? obwohl, die deutsche Sprache hat ja 5 mal so viele Wörter wie die englische, ich hoffe man findet da eins 😃



  • Feld.



  • Alles klärchen!



  • Swordfish schrieb:

    Feld.

    In der deutschen Übersetzung vom K&R (1. Auflage) heißt es Vektor. 😉

    Fast überall anders heißt es aber Feld.



  • DirkB schrieb:

    [...]

    Du mir besser sagen, was in Deinem "Eher nicht, da [...]" sich irgendwie auf mein Beispiel beziehen tut, hugh.



  • Swordfish schrieb:

    wtf?

    Bei K&R war weder const noch void bekannt.

    Daher keine hässliche Parameterliste und schlechtes Beispiel.



  • Was haltet ihr von diesem Buch?
    Mit diesem lerne ich gerade.

    https://www.amazon.de/als-erste-Programmiersprache-Einsteiger-Fortgeschrittenen/dp/3834812218

    Eine lustige Geschichte nebenbei:
    Unser C-Professor hat uns Bücher von Jürgen Wolf empfohlen, und das Standardwerk von Ritchie und Kernighan ein "schlechtes Buch" genannt. Ich frage ihn warum es schlecht sei, er sagte: Es ist didaktisch schlecht aufgebaut. 😃



  • DirkB schrieb:

    Swordfish schrieb:

    wtf?

    Bei K&R war weder const noch void bekannt.

    wo siehst Du in meinem Beispiel ein const . Das void denk dir bitte einfach weg. Die Frage war, ob T var[] auch in K&R Parameterlisten schon statt T * var üblich war.



  • Achso.
    Ja, das war möglich:
    Aus https://ia801303.us.archive.org/1/items/TheCProgrammingLanguageFirstEdition/The%20C%20Programming%20Language%20First%20Edition%20%5BUA-07%5D.pdf Seite 36.

    strlen(s) /* return length of s */
    char s[]; 
    ( 
      int i;
      i = 0;
      while (s[i] != '\0')
        ++i;
      return(i);
    }
    

    Das const hattest du von SeppJ zitiert (der es vorher angemerkt hatte), und das Zitat als hässlich bezeichnet.
    Das du die [] gemeint hast, ist nicht so deutlich rüber gekommen.



  • Dexter1997 schrieb:

    Und was wäre ein deutsches Wort für Array, das unmißverständlich ist, oder gibt es da keinen deutschen begriff? obwohl, die deutsche Sprache hat ja 5 mal so viele Wörter wie die englische, ich hoffe man findet da eins 😃

    also ich persönlich bevorzuge http://dict.tu-chemnitz.de für übersetzungen und wenn ich da array eingebe erhalte ich

    Variablenfeld {n}; Datenfeld {n}; Feld {n} (Variablenfolge, die gemeinsam angesprochen wird) [comp.] [anhören]

    das funktioniert z.b. auch mit pointer und integer.


Anmelden zum Antworten