Problem mit fread

thekiller

Viceinator
Hallo,

ich habe gerade ein sehr merkwürdiges Problem mit fread. Also ich habe mir Speicher für den kompletten Inhalt der Datei reserviert(typ char). Naja um genau zu sein ich reserviere für ein Byte mehr als die Datei groß ist.
So und wenn ich nun mit fread die Datei in den Speicher laden will, dann läd er mit immer ein paar Byte zu viel ein....Also in meinem Pointer stehen dann keine 40 Zeichen sondern 46 oder so...Obwohl ich nur als Datengröße 1 Byte angebe und die Dateilänge von 40(in diesem Beispiel)
Naja ich hoffe Ihr versteht wie ich das meine...
Ich arbeite übrigends mit dem Visual Studio. Ein Freund von mir hatte das Problem wohl auch mal, aber er weiß nicht mehr wie er das behoben hat...

Need help

MfG Manuel
 
Hi.
ich habe gerade ein sehr merkwürdiges Problem mit fread. Also ich habe mir Speicher für den kompletten Inhalt der Datei reserviert(typ char). Naja um genau zu sein ich reserviere für ein Byte mehr als die Datei groß ist.
So und wenn ich nun mit fread die Datei in den Speicher laden will, dann läd er mit immer ein paar Byte zu viel ein....Also in meinem Pointer stehen dann keine 40 Zeichen sondern 46 oder so...
Wie überprüfst du das denn? fread gibt die Anzahl der gelesenen Objekte zurück. Wieviel Objekte werden denn eingelesen?

Vermutlich willst du das gelesene als String interpretieren. Dann mußt du allerdings den String noch terminieren.

Gruß
 
Ich prüfe das mit dem Debugger von VS. Naja das funktioniert leider auch nicht mit dem Terminieren. Ich kopier mal den Teil rein wo das Problem auftritt.

C++:
....
...
...
File	= fopen(_lpFileName, "rt");
		if(File	== NULL) {
			...
			return false;
		}
		
		// Dateigröße ermitteln
		fseek(File, 0, SEEK_END);
		iFileSize	= ftell(File);
		fseek(File, 0, SEEK_SET);
		
		// Speicher reservieren für komplette Datei
		lpFileContent	= (LPSTR)new BYTE[iFileSize + 1];
		if(lpFileContent == NULL) {
			...
			return false;
		}
		
		// Datei einlesen
		fread(lpFileContent, 1, iFileSize, File);
		lpFileContent[iFileSize]	= 0;
...
..
..
 
Zuletzt bearbeitet von einem Moderator:
C++:
		// Datei einlesen
		fread(lpFileContent, 1, iFileSize, File);
		if(lpFileContent	== NULL) {
			...
			return false;
		}
Wie sollte denn an der Stelle lpFileContent NULL sein? Du hast doch vorher Speicher reserviert und auch noch (unnötigerweise) überprüft ob der Zeiger NULL ist. Da kann der Zeiger an der Stelle nun unmöglich plötzlich NULL sein... :confused:

Du solltest generell die Rückgabewerte der Funktionen prüfen, ob fseek und ftell überhaupt erfolgreich war...

Der Fehler ist vermutlich das du die Datei im Textmodus öffnest. Ansonsten, was ist der Wert von iFileSize, der Rückgabewert von fread und wie ist die aktuelle Dateigröße?

Gruß
 
Zuletzt bearbeitet von einem Moderator:
Hm kann sein, dass sich die Abfrage auf NULL nach fread beim Ändern von Quellcode eingeschlichen hat...Is mir bevor du das gesagt hast gar net aufgefallen...Naja aber das beeinträchtig ja nich den Rest.
Ja ftell() gibt die richtige Dateigröße zurück. Ich schau jetzt aber mal ob das vielleicht wirklich am Modus liegt

EDIT: Nein am Modus liegts net...versteh nich warum der da so ein Mist macht...sonst klappts auch immer...
 
Zuletzt bearbeitet:
Hm okay wenn du jetzt noch erklärst warum du alles mögliche (WinAPI-Typedef's, c file management, und c++ memory management) mischt, kann man dir helfen ;)

Wie sollte denn an der Stelle lpFileContent NULL sein? Du hast doch vorher Speicher reserviert und auch noch (unnötigerweise) überprüft ob der Zeiger NULL ist. Da kann der Zeiger an der Stelle nun unmöglich plötzlich NULL sein...
confused.gif
Ist so nicht ganz korrekt. Wenn er es korrekt gemacht hätte wäre es durchaus sinnvoll hier auf NULL zu testen, hat er aber nicht :P Dann könnte er hier auf eine Exception testen.
C++:
ptr_content  = new (std::nothrow) char[size + 1];
if (ptr_content == NULL)
{
    std::cerr << "ERROR: Datei kann nicht vollständig in den Speicher geladen werden!";
    return 1;
}
So macht es wieder Sinn ;)


C++:
FILE* ptr_file = fopen(filename, "r");
if (ptr_file == NULL) return false;

// Dateigröße ermitteln
fseek(ptr_file, 0, SEEK_END);
int size  = ftell(ptr_file);
rewind(ptr_file);

// Speicher reservieren für komplette Datei
char* ptr_content = (char*) malloc(sizeof(char) * size);
if (ptr_content == NULL)  return false;

 // Datei einlesen
if (fread(ptr_content, 1, size, ptr_file) != size)
{
    perror("ERROR:");
    return false;
} 

// Datei schließen
fclose(ptr_file);

// TODO:

// Speicher freigeben
free(ptr_content);
;)
 
Zuletzt bearbeitet:
Hi.
Hm kann sein, dass sich die Abfrage auf NULL nach fread beim Ändern von Quellcode eingeschlichen hat...Is mir bevor du das gesagt hast gar net aufgefallen...Naja aber das beeinträchtig ja nich den Rest.
Ja ftell() gibt die richtige Dateigröße zurück. Ich schau jetzt aber mal ob das vielleicht wirklich am Modus liegt

EDIT: Nein am Modus liegts net...versteh nich warum der da so ein Mist macht...sonst klappts auch immer...
Nochmal: was ist der Wert von iFileSize, der Rückgabewert von fread und wie ist die aktuelle Dateigröße?

Es kann doch nicht so schwer sein 3 einfache Fragen zu beantworten. :rolleyes:

devDevil hat gesagt.:
deepthroat hat gesagt.:
Wie sollte denn an der Stelle lpFileContent NULL sein? Du hast doch vorher Speicher reserviert und auch noch (unnötigerweise) überprüft ob der Zeiger NULL ist. Da kann der Zeiger an der Stelle nun unmöglich plötzlich NULL sein... http://www.tutorials.de/forum/images...s/confused.gif
Ist so nicht ganz korrekt.
Doch, ist es. Erstens bezog sich meine Bemerkung hauptsächlich auf die Stelle nach dem fread. Da stimmst du mir sicher zu, das es Unsinn ist auf NULL zu testen. (Zumal es bereits ein Fehler wäre der fread Funktion einen Nullzeiger zu übergeben)

Die Anmerkung mit dem vorher "unnötigerweise" auf NULL zu testen, bezog sich auf die Stelle wo er Speicher mit dem new[] Operator alloziert hat, der eine std::bad_cast Exception wirft wenn kein Speicher reserviert werden konnte. Er hat eben nicht die "nothrow" Variante gewählt und deshalb war es unnötig den Zeiger auf NULL zu testen.
devDevil hat gesagt.:
Wenn er es korrekt gemacht hätte wäre es durchaus sinnvoll hier auf NULL zu testen, hat er aber nicht :P Dann könnte er hier auf eine Exception testen.
Eben. Also war doch alles richtig was ich gesagt habe... :p

Auch du vergisst aber in deinem Code die Prüfung der Rückgabewerte... ?

Gruß
 
Zurück