Problem mit Doppelpointer (für fortgeschrittene)



  • Programmiere in C und nicht in C++



  • ok



  • genau, das ist das Problem 😉
    C!

    das habe ich im C- Kurs in der Ausbildung angefangen, weil mir langweilig war, und da sollten wir C üben... ist also zwar keine Pflicht, aber so lernt man besser den Umgang mit Pointern.

    Nur bin ich jetzt an den Punkt wo ich nicht mehr weiterkomme.

    Ich kann auch den ganzen Quell- Code hochladen, wenn es hier im Forum geht,damit ihr es ausprobieren könnt. Müsst mir nur sagen, wie man es macht...



  • Um den Fehler zu finden, könntest du assert benutzen.
    In assert.h ist assert defienirt.
    Im unteren code, wo ich den fehler vermutte hab ich assert reingemacht.
    Falls zur Laufzeit ein assert auftritt wird über den reservierten bereich geschrieben.

    /****** Auslesen der Zeilen und Speichern in unterschiedlichen Variablen ******/
    
        for( i = 0, ZeichenNr = 0; Str[ZeichenNr] != '\0' ; i++, ZeichenNr++)  //so lange Wiederholen, bis ein '\0' eingelesen wird, d.h. das Dateiende erreicht ist.
                                               //EOF wurde in einer anderen Funktion mit '\0' ersetzt im String.
        {
            for(j = 0; (Str[ZeichenNr] != '\n') && (Str[ZeichenNr] != '\0'); ZeichenNr++, j++)
            {
                assert( i < AnzahlZeilen );
                assert( j < AnzahlZeichen );
                Inhalt[i][j] = Str[ZeichenNr];
            }
    
            if(Str[ZeichenNr] == '\0')  // ZeichenNr um 1 reduzieren, wenn ein '\0' ermittelt wird, weil am Ende ZeichenNr um 1 erhöht wird
            {
                ZeichenNr = ZeichenNr - 1;
            }
            printf("%i", **Inhalt);
        }
    }
    


  • hmmm...

    assert bringt keine fehlermeldung zurück. ich schau auch in andere stellen nach... falls ich was finde melde ich mich nochmal...



  • frage: ist "assert(Str[ZeichenNr] != '\0');" zulässig?
    weil das programm stürzt bei mir dann ab.
    er erwartet assert(int), ne?



  • assert ist ein Makro, d. h. ist nicht Typsicher. Ich habe eher den Verdacht, dass dein Index nicht gültig ist. Bekommst du eine access violation?

    greetz, Swordfish



  • es wird nichts mit access violation ausgegeben, aber das Programm stürzt einfach ab, und das lässt mich vermuten, dass es eine access violation sein muss.

    das hässliche ist, dass ich devc++ verwende und dass das debugging nicht geht. kennt ihr eine andere IDE, die freeware und besser ist? (mit guter debugging funktion?)



  • Visual Studio 2008 Express Edition.



  • Du uebergibst eine Kopie der Adresse auf die *"char *Inhalt" zeigt an Deine funktion "getrow".
    Alles was Du dann in "getrow" damit anstellst, hat keinen Einfluss auf das tatsaechliche "Inhalt".

    Vorschlag:

    char** getrow(char Str[], int AnzahlZeilen, int AnzahlZeichen)
    {
      char **Inhalt;
      ...
      return Inhalt;
    }
    

    oder:

    getrow(String, &Inhalt, Zeilen, ZeichenProZeile);
    ...
    void getrow(char Str[], char ***Inhalt, int AnzahlZeilen, int AnzahlZeichen) 
    {
      *Inhalt = (char **)malloc(AnzahlZeilen * sizeof(char *)); 
      ...
    }
    

    darueber hinaus solltest du sicherstellen, dass hier:

    Inhalt[i][j] = Str[ZeichenNr];
    

    0<=i<AnzahlZeilen und 0<=j<AnzahlZeichen gilt.



  • Hab deinen 2. Codevorschlag veruscht.

    demnach müsste das allokieren der 2. Dimension so lauten:

    for(i = 0; i < AnzahlZeilen; i++) 
        {
    		**(Inhalt + i) = (char *)malloc(AnzahlZeichen * sizeof(char));
    	}
    

    da stürzt aber das programm ab, nachdem i den wert 3 erreicht... hab ich da nen fehler gemacht?

    für den 2. Vorschlag hab ich die schleife so ergänzt, zur sicherheit:
    for( i = 0, ZeichenNr = 0; Str[ZeichenNr] != '\0' || i < AnzahlZeilen; i++, ZeichenNr++)

    Übrigens: Danke für die tolle Hilfe, die hier geleistet wird! 👍



  • hab mal das ganze Programm hochgeladen ins web, damit es auch mal ausprobiert werden kann...
    so findet man evtl. leichter den fehler...

    http://www.loaditup.de/179493.html



  • hat keiner einen neuen Verbesserungsvorschlag 😕



  • In deiner getstr-Funktion holst du zu wenig speicher für Str:

    Str = malloc( sizeof(laenge) );
    

    Das sizeof ist hier falsch. In laenge steht, wie lang die Datei ist. sizeof( laenge ) ergibt aber nur die Größe einer size_t-Variablen.

    In getrow greifst du falsch auf Inhalt zu:

    **(Inhalt + i)
    

    Damit inkrementierst du Inhalt selbst, den Zeiger auf dein char**. Dort steht aber nichts. Du musst das inkrementieren, auf das Inhalt zeigt:

    *((*Inhalt) + i) = malloc(AnzahlZeichen * sizeof(char));
    

    Und hier stolperst du über die Operatorreihenfolge:

    *Inhalt[i][j] = Str[ZeichenNr];
    

    [] bindet stärker als *. Du musst also klammern:

    (*Inhalt)[i][j] = Str[ZeichenNr];
    


  • ok, es geht.

    im 1. allokieren, hattest du einen kleinen fehler noch drin gehabt (1 * zu viel) (auf mein verschulden vlt.)

    das mit getstr stimmt, aber komischerweise funktionierts auch, wenns falsch ist..

    danke!



  • und noch ne frage zum Verständniss:

    In "Inhalt" steht die Adresse der Variablen.

    Also kann ich **(Inahlt + i) schreiben, da ich ja lediglich die Adresse um i erhöhe.

    genauso wie *((*Inhalt)+i) den Inhalt von *Inhalt um i erhöht (also auch die Adresse um i) und dann dereferenziert wird.



  • Jetzt wollte ich die Zeilenlänge variabel machen, und dafür die einzelnen Zeilenlängen in einem dynamischen Array speichern, welches einer Funktion per Call-by-Reference übergeben wird, doch da kommt folgende Fehlermeldung in der Funktion: "assignment makes pointer from integer without a cast"

    void ReadDocLength(int *AnzahlZeilen, int **AnzahlZeichen, char Str[])
    {			
    		int ZeichenNr = 0;
    		char Zaehler;
    		int i = 0;
    
    		/* Anzahl der Zeichen lesen und in "AnzahlZeichen" speichern */
    
    	for(ZeichenNr = 0, i = 0, *(AnzahlZeichen+0) = 0, Zaehler = 1; Str[ZeichenNr] != '\0'; ZeichenNr++)
    	{
    	    *(AnzahlZeichen+i) = Zaehler ;  // DIESE ZEILE HAT DEN FEHLER
    		Zaehler++;
    
    printf("\nAnzahlZeichen[i]: %i", *(AnzahlZeichen+i));
    
    		if(Str[ZeichenNr] == '\n')
    		{
    			i++;
    			Zaehler = 0;
    		}	
    	}	
    
    system("pause");
    

Anmelden zum Antworten