Probleme mit malloc



  • Hallo, ich habe folgendes Programm gebastelt. Es soll das klassische Hangmanspiel mit einfachen Textausgaben sein.Ich hatte es schritt für schritt aufgebaut, also sollten die ein bzw ausgaben funktionieren. Als letzten schritt habe ich 2 arrays mit malloc reservieren wollen(zeile 48), allerdings wirft das starke probleme auf. Ich habe leider keine erfahrungen mit malloc, habe mich aber (soweit ich das jetzt gesehen habe) streng an die grund syntax gehalten...
    Das problem ist, dass wenn ich eine wortlänge von zb 5 oder 6 eingebe das dargestellte array immer nur 4 Werte beinhaltet.
    Vielleicht kann mir ja wer helfen... Wäre echt super 🙂

    #include<string.h>
    #include<stdio.h>
    #include <stdlib.h>
    
    void funktion(char* wortrat){
    int i=0,laenge=2000;
    while(laenge!=i)
        {                           //Ersetzt ein sizeof(),welches hier nicht funktioniert
        if (wortrat[i]=='\0')                   //laenge = sizeof(wortrat);
                {
                laenge=i;
                }
        else
        {
        i++;
        }
    }
    for(i=0;i<(laenge-2);i++)
        {
        printf("%c ",wortrat[i]);
        }
    printf("\n\n");
    }
    
    int main(void)
    {
    //Deklaration
    int laenge=0;
    char raten='a';
    int fehler=0;
    int merkerf=0;
    int win=0;
    int i;
    
    //Intro
    system("cls");
    printf("\n\n\t*******************");
    printf("\n\t* HANGMAN *");
    printf("\n\t*******************\n\n");
    system("PAUSE");
    system("cls");
    
    //Worteingabe
    printf("Geben sie die laenge des Wortes an: ");
    scanf("%i",&laenge);
    // Arrays erstellen
    char*wort=(char*)malloc(laenge*sizeof(char));
    char*wortrat=(char*)malloc(laenge*sizeof(char));
    
    if (wort==0||wortrat==0){printf("Fehler bei malloc!!!\n\n Es steht nicht genug speicher zur verfügung!");
    goto Programm_beenden;}
    printf("Geben sie da Wort ein");
    for(i=0;i<sizeof(wort);i++)
        {
        wort[i]=getche();
        }
    //Einmalige wortausgabe zur Überprüfung
    printf("\nIhr wort ist: ");
    for(i=0;i<laenge;i++)
        {
        printf("%c",wort[i]);
        }
    printf("\n\n\n");
    system("PAUSE");
    system("cls");
    //Rate Array mit "_" füllen
    for(i=0;i<sizeof(wort);i++)
        {
        wortrat[i]='_';
        }
    //Rateroutine
    printf("Raten sie einen Buchstaben. Wenn sie 9 mal falsch raten verlieren sie\n");
    printf("Das wort hat %i Buchstaben\n\n",sizeof(wort));
    
    while(fehler<=9)
        {
    
        printf("\n\n");
        //Übergabe an Funktion zur Ausgabe
        funktion(wortrat);
        printf("\nraten sie: ");
        scanf("%s",&raten);
    
            for(i=0;i<sizeof(wort);i++)
            {
            if(raten==wort[i]&&raten!=wortrat[i])
                {
                printf("Buchstabe %c, ist richtig\n",raten);
                wortrat[i]=raten;
                merkerf=1;
                win++;
                }
            }
        if(merkerf==0)
            {
            printf("Buchstabe %c ist leider nicht dabei\n",raten);
            fehler++;
            }
        system("pause");
        system("cls");
        printf("\nsie koennen noch %i mal falsch raten\n",9-fehler);
        merkerf=0;
    
        if(win==sizeof(wort))
            {
            printf("Gewonnen!");
            break;
            }
    if (fehler>=9)
            {
            printf("Verlohren!\n");
            break;
            }
    }
    Programm_beenden:
    system("PAUSE");
    return 0;
    }
    


  • Oh mist sehe gerade das ich den free befehl noch nicht eingebaut habe. hat aber auch nichts an der grundsituation geändert 😕



  • Oh, oh, ich sehe viele grundlegende Fehler!

    Das was du in "funktion" suchst heißt strlen (auch Zeile 68,85).
    Dein goto macht es etwas unübersichtlich, besser wäre bspw. return EXIT_FAILURE.
    Was soll die Methode in Zeile 56 sein?

    Ich hab jetzt aber leider keine Zeit mehr... Soll jemand anders weiterhelfen :).



  • Hey sauber danke! Ja mache das noch nicht lange bin auch über grundlegende tips froh 🙂 strlen kannte ich noch nicht, aber genau das fehlte mir 🙂 mit der methode in 56 wollte ich das wort füllen, also array[0]-> getche(), array[1]->getche... usw. return EXIT_FAILURE kenne ich noch nicht, schaue ich mir aber direkt mal an 🙂



  • So habe nun nochmal den code überarbeitet.

    #include<string.h>
    #include<stdio.h>
    #include <stdlib.h>
    
    void funktion(char* wortrat){
    int i=0,laenge=2000;
    laenge = strlen(wortrat);
    for(i=0;i<(laenge-2);i++)
        {
        printf("%c ",wortrat[i]);
        }
    printf("\n\n");
    }
    
    int main(void)
    {
    //Deklaration
    int laenge=0;
    char raten='a';
    int fehler=0;
    int merkerf=0;
    int win=0;
    int i;
    
    //Intro
    system("cls");
    printf("\n\n\t*******************");
    printf("\n\t* HANGMAN *");
    printf("\n\t*******************\n\n");
    system("PAUSE");
    system("cls");
    
    //Worteingabe
    printf("Geben sie die laenge des Wortes an: ");
    scanf("%i",&laenge);
    // Arrays erstellen
    char*wort=(char*)malloc(laenge*sizeof(char));
    char*wortrat=(char*)malloc(laenge*sizeof(char));
    
    if (wort==0||wortrat==0){printf("Fehler bei malloc!!!\n\n Es steht nicht genug speicher zur verfügung!");
    return EXIT_FAILURE;}
    printf("Geben sie da Wort ein");
    for(i=0;i<sizeof(wort);i++)
        {
        wort[i]=getche();
        }
    //Einmalige wortausgabe zur Überprüfung
    printf("\nIhr wort ist: ");
    for(i=0;i<laenge;i++)
        {
        printf("%c",wort[i]);
        }
    printf("\n\n\n");
    system("PAUSE");
    system("cls");
    //Rate Array mit "_" füllen
    for(i=0;i<sizeof(wort);i++)
        {
        wortrat[i]='_';
        }
    //Rateroutine
    printf("Raten sie einen Buchstaben. Wenn sie 9 mal falsch raten verlieren sie\n");
    printf("Das wort hat %i Buchstaben\n\n",sizeof(wort));
    
    while(fehler<=9)
        {
    
        printf("\n\n");
        //Übergabe an Funktion zur Ausgabe
        funktion(wortrat);
        printf("\nraten sie: ");
        scanf("%s",&raten);
    
            for(i=0;i<sizeof(wort);i++)
            {
            if(raten==wort[i]&&raten!=wortrat[i])
                {
                printf("Buchstabe %c, ist richtig\n",raten);
                wortrat[i]=raten;
                merkerf=1;
                win++;
                }
            }
        if(merkerf==0)
            {
            printf("Buchstabe %c ist leider nicht dabei\n",raten);
            fehler++;
            }
        system("pause");
        system("cls");
        printf("\nsie koennen noch %i mal falsch raten\n",9-fehler);
        merkerf=0;
    
        if(win==sizeof(wort))
            {
            printf("Gewonnen!");
            break;
            }
    if (fehler>=9)
            {
            printf("Verlohren!\n");
            break;
            }
    }
    system("PAUSE");
        free(wort);
        free(wortrat);
    
    return 0;
    }
    

  • Mod

    Wichtig:

    • Bessere Bezeichner! (lol: void funktion )
    • Const-correctness
    • char*wort ... sizeof(wort) . Völlig falsch.
    • %i ist nicht der Formatspezifizierer für size_t
    • Programmlogik: Was, wenn nur eines 0 ist, wort oder wortrat? Dann wird nicht aufgeräumt!

    Nicht ganz so wichtig:

    • Wozu printf ohne zu formatierende Argumente? puts und putchar!
    • Unsinnige Initialisierungen:
    int laenge=2000; // WTF?
      laenge = strlen(wortrat);
    
      // ->
      int laenge = strlen(wortrat);
    
    • Unsinnige Casts, die Fehler verdecken können (malloc)
    • sizeof(char)==1 per Definition
    • Spendier dem Code ein paar Leerzeichen und Zeilenumbrüche!
    • Du benutzt offensichtlich C99, dann sei auch konsequent und mach alle Deklarationen so lokal wie möglich
    • Oder benutzt du etwa einen C++-Compiler? Sei dir sicher, dass du einen C-Compiler benutzt!
    • Füllen = memset
    • Können Längen negativ sein?
    • Däutsche Rechtssschraibunk!

    Ich habe jeweils nur ein Beispiel zu den Punkten gebracht, fast alles trifft mehrmals auf deinen Code zu.



  • SeppJ schrieb:

    Wichtig:

    • Bessere Bezeichner! (lol: void funktion )
    • Const-correctness
    • char*wort ... sizeof(wort) . Völlig falsch.
    • %i ist nicht der Formatspezifizierer für size_t
    • Programmlogik: Was, wenn nur eines 0 ist, wort oder wortrat? Dann wird nicht aufgeräumt!

    Nicht ganz so wichtig:

    • Wozu printf ohne zu formatierende Argumente? puts und putchar!
    • Unsinnige Initialisierungen:
    int laenge=2000; // WTF?
      laenge = strlen(wortrat);
    
      // ->
      int laenge = strlen(wortrat);
    
    • Unsinnige Casts, die Fehler verdecken können (malloc)
    • sizeof(char)==1 per Definition
    • Spendier dem Code ein paar Leerzeichen und Zeilenumbrüche!
    • Du benutzt offensichtlich C99, dann sei auch konsequent und mach alle Deklarationen so lokal wie möglich
    • Oder benutzt du etwa einen C++-Compiler? Sei dir sicher, dass du einen C-Compiler benutzt!
    • Füllen = memset
    • Können Längen negativ sein?
    • Däutsche Rechtssschraibunk!

    Ich habe jeweils nur ein Beispiel zu den Punkten gebracht, fast alles trifft mehrmals auf deinen Code zu.

    Gut die Bezeichner das stimmt wohl, da war ich nicht wirklich kreativ 😛 was meinst du mit Const-correctness? was ist der richtige Formatspezifizierer für size_t? Zu dem free befehlen hab die nun auch in die if schleife vor das return gesetzt. nun wird der Speicher auf jeden fall wieder frei gemacht. Wofür sollte ich mit memset füllen?


  • Mod

    Berninghaus8989 schrieb:

    was meinst du mit Const-correctness?

    Das:
    Google: const-correctness

    Genauer, die Signatur deiner Funktion funktion (dieser Name 🙄 ), die wohl eher void funktion(const char* wortrat) sein sollte. Da das ein allgemein wichtiges Thema ist, solltest du nicht nur diesen Vorschlag blind übernehmen, sondern auch obigem Link mal folgen und verstehen, warum das so besser ist.

    was ist der richtige Formatspezifizierer für size_t?

    Das ist ein bisschen schwierig, leider gibt es darauf keine einfache Antwort (->Google). Nimm es nur als Hinweis für später. Derzeit brauchst du es gar nicht, da es von dem sizeof kommt, was an der Stelle jedoch ein schwerer Fehler ist, der korrigiert werden muss. Überhaupt kennst du doch die Länge des Wortes schon, schließlich wurde es oben angegeben.

    Wofür sollte ich mit memset füllen?

    Weil's einfacher ist 🙂 . Nun, anscheinend siehst du das anders, dann mach es eben mit Handarbeit.



  • ...



  • WOW danke! die funktion kann ich zwar (noch) nicht nachvollziehen, aber das wird sich ändern. zu den constant das schaue ich mir auf jeden fall an! Sieht ja schon herrlich strukturiert aus! Geil 😃

    Danke an alle die sich beteiligt haben !
    zum stil... naja hatte zwar informatikvorlesungen aber eigentlich ist das mehr oder weniger selbst beigebracht weil der prof ziemlich schusslig ist.
    Ich werde mir aber auf jeden fall von deinem stil einiges abschaun!



  • So, eine sache noch... das clrscr() "clear screen" bedeutet da bin ich nun auch hinter gekommen, nur was bedeutet "if( !wort )"? kenne das nur als normales "not". aber mit was vergleicht die if funktion denn dann das array?



  • ...



  • Klar hab da noch massig probleme, aber deshalb geb ich mich ja ran.(nagut ne klausur gibts da auchnoch 😉 ). Trotzdem danke für die hilfe. Und dann schaue ich mir nicht zuviel ab, sondern suche nur mal die tab taste und lass ab und zu sinnvoll eine zeile frei 🙂



  • ...


Anmelden zum Antworten