Noob: File auslesen mit fread(); Speicherverletzungen



  • Hallo Leute,

    Habe ein Problem, oder besser gesagt 2 Speicherverletzungen während der Laufzeit.

    Der Code ist Teil der Einlesefunktion für HTML-Dateien von meinen Webserver, gestern Nacht lief das ganze auch mal variabel mit mehreren tausend Zeichen, aber nachdem ich heute was verändert habe gehts nicht mehr *hilflos*.
    Die auszulesende Datei index.html hat eine Länge von gerade mal 16 Zeichen, dafür müsste der Buffer datei doch eigentlich reichen, oder?
    Eigentlich mag ich ja einen unbegrenzten Buffer haben (buffer<2GB) oder geht das nicht mit nullterminierten strings? Kann ich ned einfach so nen Zeiger
    char* daten;
    anlegen und dem was beliebig langes zuweisen?

    #include <iostream.h>
    #include <stdio.h>
    
    int main()
    {
    	char* datensaetze;
    	char* datei="Hallo Welt, Hallo Welt, Hallo Welt";
    	FILE* f=fopen("index.html","rb");
    	while((feof(f))==0)
    	{
    	fread(datensaetze,sizeof(char),1,f);
            //nur dass ich dass hier nicht falsch verstehe:
            //datensätze ist pointer auf den buffer in den das gelesene kommt
            //sizeof(char)jeweils ein byte (also auch zb. ein char)speicher wird   
            //ausgelesen , wobei das hier nur einmal gemacht wird
            //ist es effektiver wenn ich gleich 512 hole oder
            //riskiere ich damit eher einen pufferüberlauf
    	datei=strcat(datei, datensaetze);
    	}
    	fclose(f);
    	return 0;
    }
    

    Verbesserungsvorschläge die zu besserem, schnelleren oder nur schönerem CODE führen sind immer willkommen 😋

    Vielen Dank
    schon im Voraus

    Gruß TheChosn



  • du kannst schon einen pointer nehmen, musst dann aber auch platz mit malloc() / calloc() / realloc() reservieren.



  • du bekommst eine zugriffsverletzung, weil du keinen speicher
    fuer fread bereitgestellt hast.

    /* das ist ein ZEIGER auf ein char
     * der zeigt auf irgendeinen speicherbereich
     * (der mit grosser wahrscheinlichkeit nicht dir
     * gehoert).
     */
    char* datensaetze;
    
    /* jetzt hast du genau 512 bytes speicher
     */
    char buffer[512];
    
    /* mit fread solltest du in bloecken lesen
     * also z.b. 512
     * (natuerlich kannst du auch immer nur ein byte lesen,
     * was aber ineffektiv ist).
     */
    fread(buffer,sizeof(char),512,f);
    

    du kannst auch nicht strcat verwenden.
    strcat sucht nach einem '\0' und haengt danach den zweiten
    string an.
    fread haengt jedoch kein '\0' an!

    warum bindest du iostream ein? die brauchst du hier nicht (c++).



  • Danke für die schnelle Hilfe

    was ich verschwiegen habe ist,
    dass das Programm ist eigentlich c++ ist.
    Da aber die Funktion fopen()
    meines wissens noch c ist hab ich gedacht
    ich tus in dieses Forum.

    Wie kann ich die beiden strings dann verketten
    ohne dass ich eine
    "unzulässige zeigeraddition" bekomme?

    Gruß TheChosn



  • wenn dein programm c++ ist, dann arbeite am besten
    mit den fstream klassen.
    dazu nimmst du noch die string klasse; du kannst
    strings ganz einfach aneinanderhaengen mit s1 + s2.
    schau mal in die c++ faq (stroeme und dateien, und such nach string).

    ansonsten, wenn du bei c bleiben willst wuerde ich es mit memcpy
    machen (aus <string.h>):

    char* grosserBuffer = malloc( 4048 ); /* oder auch mehr */
    char* tmp = grosserBuffer;
    while ( ( long bytes = fread( buffer,....) ) > 0 )
    {
      memcpy( tmp, buffer, bytes );
      tmp += bytes;
    }
    free( grosserBuffer );
    

    aber wenn du wirklich ganze dateien ins ram einlesen willst,
    solltest du os-spezifische funktionen verwenden; frag am besten
    im winapi oder linux forum nach, je nachdem.



  • Danke aber sooo tief wollte ich dann doch nicht in die C materie eintauchen,
    mir reicht mein new/ delete völlig 😃
    aber die fstreams werd ich mir mal zu herzen nehmen

    Gruß TheChosn


Anmelden zum Antworten