Eine Liste erstellen



  • Das funktioniert soweit.
    Nun hab ich noch einen Fehler, wenn er das Programm beendet, beim freigeben des Speichers.

    "Debug Error

    HEAP CORRUPTION DETECTED: after Normal Block (#60) at 0x000D31E0.
    CRT detected that the application wrote to memory after the end of heap buffer."

    Weiss jemand was ich falsch mach?



  • Hi!

    Ich weiß nicht an was es liegen könnte da es bei mir funktioniert. Das Bild von dir ist super, jetzt weiß ich was du meinst, leider bekomme ich den Fehler selbst nie. Das mit:

    guess[strlen(solution)] = '\0';
    

    ist aber eine gute Idee und bewirkt in deinem Fall Wunder, nur eigentlich müsste an dieser Stelle schon diese Zeichen stehen. Tuts bei mir auch.
    Daher kann ich auch zu deinem Heap Problem nichts sagen, da das bei mir auch funktioniert.
    Ich hab hier mal mein Hangman.exe (compiliert mit DMC unter WinXP Pro 32bit) hochgeladen, probier das mal aus und sag mir ob es Fehler wirft? Vielleicht kannst du mir auch dein Hangman.exe hochladen, dann kann ich schauen ob es bei mir funktioniert.

    Lg THE_ONE

    hangman.exe: http://rapidshare.com/files/129558232/hangman.exe



  • Seit ich

    guess[strlen(solution)] = '\0';
    

    drin habe, kommen diese komischen Zeichen aus meinem Bild nicht mehr 😃

    Aber komisch das du keinen Heapfehler bekommst 😕



  • Irgendwie fehlt bei dir das EndOfString und mit der eine Zeile bewirkst du genau das, verstehe aber nicht warum bei dir das EndOfString überhaupt fehlt 😕

    Hast du meine exe ausprobiert, funktioniert sie oder bekommst du den gleichen Fehler (Heap Fehler) wieder??

    Lg THE_ONE



  • Also bei dir gehts. Kannst mir deinen Code noch mal posten, damit ich schauen kann, wo der Unterschied ist?



  • So hier nochmal der Code:

    #include "stdafx.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #define MAXNUMBEROFSTRINGS 4
    int NumberOfStrings=0;
    
    void drain_stdin (void)
    {
      int c;
      do
      {
        c = fgetc(stdin);
      } while (c != EOF && c != '\n');
    } 
    
    void addstring(char** Array, const char* String)
    {	
    	Array[NumberOfStrings]=(char*)malloc(1+strlen(String));
    	strcpy(Array[NumberOfStrings],String);
    	NumberOfStrings++;
    }
    
    void FreeArray(char** StringArray)
    {
      int i;
      for(i=0;i<MAXNUMBEROFSTRINGS;i++)
      {
        free(StringArray[i]);
      }
      free(StringArray);
    }
    
    int main(int argc, char *argv[])
    {	
    	char* solution;		/* gesuchtes Loesungswort */
        char* guess;		/* Zwischenloesung */
        char w;				/* Eingegebenes Wort der Konsole */
        int exit = 0;		/* exit = 1: While Schleife wird verlassen */
        int i,j;			/* Laufvariablen */
    	int r;				/*random*/
    
      srand(time(NULL)); /*start randomize*/
    
      char** StringArray= (char**) malloc(MAXNUMBEROFSTRINGS*sizeof(char*));
      /*add Strings here - if you add a String here,change the MAXNUMBEROFSTRINGS too*/
      addstring(StringArray,"Winter");
      addstring(StringArray,"Herbst");
      addstring(StringArray,"Sommer");
      addstring(StringArray,"Fruehling");
    
      /*choose randomized  string*/
      r= rand()%NumberOfStrings;
      solution = StringArray[r];
    
      /*initialize guess*/
      if ((guess = (char*)malloc(1+strlen(solution))) == NULL) {
        puts("Memory allocation error!");
        return 0;
      }
      else
      {
    	for(i=0; i<(strlen(solution)); i++) guess[i] = '_'; 
    	guess[strlen(solution)] = '\0';
      }
        /* Spielbeschreibung */    
        printf("Herzlich Willkommen bei Hangman!\n");
        printf("Geben Sie nach und nach einen Buchstaben ein, um das Wort zu erraten.\n");
        printf("Wenn sie das Spiel beenden moechten, geben Sie \"=\" ein.\n");
        printf("Los gehts:\n");    
        /* ---------------- */
    
        while(exit == 0){
            w = getchar();
    		drain_stdin(); 
            if (w == '=') 
    		{
    			exit = 1;      /* '=' eingeben um Spiel zu beenden */
    			free(guess);   /*Speicher leeren*/
    			FreeArray(StringArray);
    		}
    		else
    		{
    	        /* Ueberprueft, ob eingegebenes Wort im Loesungswort enthalten ist */
    	        for(i=0; i<strlen(solution); i++){
    	           if(solution[i] == w){
    	              guess[i] = w;
    	           }                                      
    	        }
    
    	       	/* Gibt bisherige Loesung aus */
    			 /*printf("%s", guess);*/
    			for(j=0; j<strlen(solution); j++){            
                    printf("%c ", guess[j]);   
                } 
    
    	        if(strcmp(solution, guess) == 0 ){
    	           printf("\n Herzlichen Glueckwunsch, Sie haben das gesuchte Wort erraten.\n");
    			   free(guess);
    			   FreeArray(StringArray);
    	           exit = 1;
    	        }
    	        printf("\n");
           }
        }
        return 1;
    }
    

    Lg THE_ONE



  • Hast du den Fehler gefunden, läuft es schon?? Würde gerne wissen wie es dir mit deinem C Programm geht.

    Lg THE_ONE



  • Hallo,

    ich habe mir eure Codes nicht ganz genau angesehen, aber zur Unterstützung der Heap-Fehlersuche:

    Alle Codes übertreten den von malloc erhaltenen Speicherblock, und zwar in der Funktion addstring hier:

    strcpy(Array[NumberOfStrings],String);
    

    und bei der Nullterminierung von guess hier:

    guess[strlen(solution)] = '\0'
    

    In beiden Fällen ist der von malloc besorgte Speicher um eine Position zu klein ausgefallen 😉

    THE_ONE schrieb:

    [...]verstehe aber nicht warum bei dir das EndOfString überhaupt fehlt

    Woher soll denn die abschliessende Null kommen? malloc tut das jedenfalls nicht, also muss man sich selber darum kümmern, wenn man so vorgeht.

    MfG,

    Probe-Nutzer



  • Probe-Nutzer schrieb:

    In beiden Fällen ist der von malloc besorgte Speicher um eine Position zu klein ausgefallen 😉 Probe-Nutzer

    da hast du recht strlen gibt ja nur die Anzahl der Buchstaben aus, ohne das abschließende '\0' Zeichen.

    Probe-Nutzer schrieb:

    THE_ONE schrieb:

    [...]verstehe aber nicht warum bei dir das EndOfString überhaupt fehlt

    Woher soll denn die abschliessende Null kommen? malloc tut das jedenfalls nicht,..

    Wenn man in C einen String angibt wird der doch immer mit '\0' abgeschlossen oder??
    Wenn man z.b. das:

    char * Wort = "Hallo"
    

    schreibt,dann ist Wort[5] = '\0'

    Lg THE_ONE

    Ps.: Der Fehler ist mir einleuchtend (stimme dir völlig zu), was mich aber wundert ist dass das Programm ohne Probleme funktioniert bei mir. An was kann das liegen?? Aus falschem Code sollte ja nicht ein korrektes Programm folgen.



  • THE_ONE schrieb:

    Wenn man z.b. das:

    char * Wort = "Hallo"
    

    schreibt,dann ist Wort[5] = '\0'

    In diesem Falle ja, aber das passiert doch gerade in eurem Programm nicht, es wird keine so "zugewiesene" Zeichenkette verwendet, sondern "roher" Speicher, der irgendetwas enthalten kann.

    THE_ONE schrieb:

    Ps.: Der Fehler ist mir einleuchtend (stimme dir völlig zu), was mich aber wundert ist dass das Programm ohne Probleme funktioniert bei mir. An was kann das liegen?? Aus falschem Code sollte ja nicht ein korrektes Programm folgen.

    Es ist nicht vorhersagbar, was passiert, wenn man solche Fehler macht, deshalb sind sie so tückisch, es kann alles gut gehen, oder abstürzen, oder sonst etwas passieren, oder es können, um das EndOfString-Problem noch hinzu zu nehmen, zufällig Nullen im von malloc besorgten Speicher liegen...

    Also kann ein Code mit solchen Fehlern, die vom Compiler unentdeckt bleiben, durchaus lauffähig sein, bis man feststellt, dass auf irgendeinem anderen System oder erst nach längerer Laufzeit Probleme auftreten.

    MfG,

    Probe-Nutzer



  • Jeden Speicher den du mit malloc reservierst solltest du am besten erstemal durch

    memset( speicher*, 0, sizeof(speicher*) );
    

    0en... dann steht überall '\0' drinn... dann solltest du auf die basis gewählter funktionen achten.. mancha geben einen int zurück, aber dann kannst ud nciht sagen

    array[strlen(array)] = '\0';
    

    sondern musst sagen

    array[strlen(array)-1] = '\0';
    

    weil dein array bei 0 losgeht aber die funktion den start 1 hat... xD



  • lippoliv schrieb:

    ...sondern musst sagen

    array[strlen(array)-1] = '\0';
    

    weil dein array bei 0 losgeht aber die funktion den start 1 hat... xD

    Hhmm...

    strlen() auf ein nicht initialisiertes Array anwenden, um damit das letzte Zeichen
    auf '\0' zu setzen ?
    Gute Nacht...



  • Probe-Nutzer schrieb:

    In diesem Falle ja, aber das passiert doch gerade in eurem Programm nicht, es wird keine so "zugewiesene" Zeichenkette verwendet, sondern "roher" Speicher, der irgendetwas enthalten kann.

    Und was ist mit

    addstring(StringArray,"Winter");
    

    Das "Winter" ist doch ein String mit abschließender '\0' oder??

    Lg THE_ONE



  • THE_ONE schrieb:

    Und was ist mit

    addstring(StringArray,"Winter");
    

    Das "Winter" ist doch ein String mit abschließender '\0' oder??

    Das ist ok, da strcpy die Null ebenfalls kopiert, und eine solche Zeichenkette immer nullterminiert ist.

    Ich habe gesehen, dass du deinen Code korrigiert hast, aber die "+1" für solution fehlt immer noch, nur so als Hinweis...

    MfG,

    Probe-Nutzer



  • @Probe-Nutzer

    Danke für deinen Hinweiß!
    Du meinst sicher folgende Zeile:

    if ((guess = (char*)malloc(strlen(solution))) == NULL) {
    

    richtig wäre

    if ((guess = (char*)malloc(1+strlen(solution))) == NULL) {
    

    Habs ausgebessert. Da sieht man wiedermal wie sich in einem kleinen Programm schon zig Fehler einschleichen können.

    Danke nochmal für deine Hilfe, THE_ONE



  • bladerunner10 schrieb:

    lippoliv schrieb:

    ...sondern musst sagen

    array[strlen(array)-1] = '\0';
    

    weil dein array bei 0 losgeht aber die funktion den start 1 hat... xD

    Hhmm...

    strlen() auf ein nicht initialisiertes Array anwenden, um damit das letzte Zeichen
    auf '\0' zu setzen ?
    Gute Nacht...

    Wieso nicht initialisiert? Ist doch jedem klar was ich meine! array ist keine Variable, sondern der Variablentyp.
    Aber wnen dus so genau haben willst

    char myArr[300] = { 0 };
    strcpy( myArr, "helloWorld" );
    myArr[strlen(myArr)-1] = '\0'; //ist überflüssig, da strcpy automatisch anhängt, aber es geht und die leute mit der Goldwage unter uns..
    

    😃


Anmelden zum Antworten