Variable aus malloc() auf 0 setzen
-
Hallo. Ich lese den Dateiinhalt mit malloc() ein, da dort binär Strings, Floats und Integer gespeichert sind. Klappt alles super. Jetzt gibt es einen Punkt, bei dem ich den Inhalt quasi auf 0 zurücksetzen möchte. Es soll keine Werte mehr in der Variable geben. Die Strings sollen leer sein, die Floats und Integer 0.
Ich dachte da spontan an ZeroMemory, aber wenn ich das nutze, dann speichert er mir seltsamerweise nicht mehr die Datei. Obwohl die Funktion return true meldet.
ZeroMemory(&data, sizeof(data));
Die Datei ist mehrere tausend Byte groß. Muss ich jetzt nochmal die Dateigröße auslesen und dann
char empty = 0; memcpy(&data[0],&empty,filesize);
machen? Welcher Weg würde man mir hier vorgeschlagen?
-
Btw
char empty = 0; memcpy(&data[0],&empty,filesize);
Das geht natürlich nicht und würde Mülldaten in data erzeugen. Darum frage ich was hier der beste Weg wäre. Korrekter wäre mit obigen Beispiel eine Schleife die je 1 Byte mit Inhalt 0 in memcpy schreibt, bis zum Dateiende.
Ich hoffe hier auf einen schnelleren Weg, anstatt über 50.000 Schleifendurchläufe zu machen.
-
Zeig mal bitte die Deklaration von data.
-
~zero schrieb:
Hallo. Ich lese den Dateiinhalt mit malloc() ein
Wie denn das? malloc ist zum reservieren von Speicher und sonst nichts. Zum Lesen von Dateien gibt es fread und ähnliches.
BTW.: Zum setzen eines Speichers auf 0 gibt es unter anderen memset.
mfg Martin
-
Also ich habe mein data
unsigned char *data;
und eine Datei lese und schreibe Funktion erstellt. Am Ende des Programmes natürlich noch das free (data);
Am Anfang des Programmes mache ich
ReadFile(FileName,&data);
und am Ende
WriteFile(FileName,&data);
Ohne ZeroMemory klappt alles wunderbar! Aber mit diesem, wird das data-file plötzlich nicht mehr aktualisiert.
//--------------------------------------------------------------------------- bool ReadFile(UnicodeString &FileName, unsigned char **var) { int handle; long filesize; char dammy[MAX_PATH]; _fmode=_O_BINARY; handle = _wrtl_open(FileName.w_str(),_O_RDONLY); if (handle==-1) { sprintf(dammy,"Error: %s (open)",FileName); ShowMessage(dammy); return false; } else { if ((filesize=filelength(handle))==-1L) { sprintf(dammy,"Error: %s (size)",FileName); ShowMessage(dammy); return false; } *var = (unsigned char*) realloc(*var,filesize+1); _rtl_read(handle,*var,filesize); _rtl_close(handle); } return true; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- bool WriteFile(UnicodeString &FileName, unsigned char **var) { int handle; long filesize; char dammy[MAX_PATH]; _fmode=_O_BINARY; handle = _wrtl_open(FileName.w_str(),_O_WRONLY); if (handle==-1) { sprintf(dammy,"Error: %s (open)",FileName); ShowMessage(dammy); return false; } else { if ((filesize=filelength(handle))==-1L) { sprintf(dammy,"Error: %s (size)",FileName); ShowMessage(dammy); return false; } long si; _rtl_write(handle,*var,filesize); _rtl_close(handle); //ShowMessage(FileName+"..."+IntToStr((__int64)filesize)); } return true; } //---------------------------------------------------------------------------
Wäre sehr nett wenn mir jemand ein Beispiel geben könnte, wie ich den kompletten Inhalt von data auf 0 setzen kann.
-
Wenn ich das ShowMessage ein wenig erweitere
int bytes = _rtl_write(handle,*var,filesize); _rtl_close(handle); char *errormsg = strerror(errno); ShowMessage(FileName+"..."+IntToStr((__int64)filesize)+"..."+IntToStr(bytes)+".."+errormsg);
Dann sagt er mir bytes = -1 und bei errormsg "Invalid Argument" als Fehler. Aber wie gesagt, nur wenn ich ZeroMemory nutze. Ich schreibe die Daten immer bei Programmende. Wenn ich den Button nicht drücke, welcher ZeroMemory aufruft, dann habe ich keine Fehler und alle Daten werden erfolgreich geschrieben.
-
Was für ein Typ hat "data" denn. Wie ist der Typ deklariert. Kannst du ein funktionierendes Minimalbeispiel liefern das den Fehler repräsentiert. Ich seh kein ZeroMemory im Code... Das wars erstmal!
-
Also ZeroMemory steht in meinem Code ja oben, das würde als Kompletter Code nur so ausschauen
void __fastcall TForm1::Button3Click(TObject *Sender) { ZeroMemory(&data,sizeof(data)); }
Und die Deklaration und Zuweisung steht hier oben etwas ausführlicher:
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1955192.html#1955192
-
Sorry für die Doppelposts ^^°
Nur um das vielleicht nochmal zu verdeutlichen. Das hier funktioniert einwandfrei. Ich würde das nur gern schneller haben und dachte dafür sei ZeroMemory gedacht.
void __fastcall TForm1::Button3Click(TObject *Sender) { char empty = 0; for (int i=0;i<55321;i++) // 55321 ist die Dateigröße in Bytes { memcpy(&data[i],&empty,1); } }
-
~zero schrieb:
ZeroMemory(&data,sizeof(data));
Wieso der Adressoperator? Du übergibst hier einen Zeiger auf einen Zeiger. Damit setzt du deine Zeiger-Variable selbst auf 0 (und verlierst den Zugriff auf den reservierten Speicher). Also lass den mal weg. Was als 2. Parameter übergeben werden soll, kann dir keiner sagen, weil du den malloc-Aufruf nicht gepostet hast. sizeof(data) ist jedenfalls falsch (das ist die Länge vom Zeiger, nicht vom Speicher, auf den der Zeiger zeigt).
-
_matze schrieb:
Was als 2. Parameter übergeben werden soll, kann dir keiner sagen, weil du den malloc-Aufruf nicht gepostet hast.
Das steht oben. Vielleicht habe ich zuviel Code rein gestellt und wurde übersehen. Aber wie gesagt, data beinhaltet eine Datei und damit eine Dateigröße.
filesize=filelength(handle) *var = (unsigned char*) realloc(*var,filesize+1);
Siehe ReadFile()
-
~zero schrieb:
_matze schrieb:
Was als 2. Parameter übergeben werden soll, kann dir keiner sagen, weil du den malloc-Aufruf nicht gepostet hast.
Das steht oben. Vielleicht habe ich zuviel Code rein gestellt und wurde übersehen. Aber wie gesagt, data beinhaltet eine Datei und damit eine Dateigröße.
filesize=filelength(handle) *var = (unsigned char*) realloc(*var,filesize+1);
Siehe ReadFile()
Ok. Klappt es denn nun ohne Adressoperator?
-
_matze schrieb:
Wieso der Adressoperator? Du übergibst hier einen Zeiger auf einen Zeiger. Damit setzt du deine Zeiger-Variable selbst auf 0 (und verlierst den Zugriff auf den reservierten Speicher). Also lass den mal weg.
Ups, Copy&Waste ^^ Ja stimmt natürlich, jetzt schreibt er die Variable endlich auch in die Datei. Danke!
Wenn ich die Dateilänge als size mit angebe, dann funktioniert es endlich wie gewollt. Die Möglichkeit aus data die Bytegröße zu bestimmen existiert ja sicherlich nicht, oder?
-
~zero schrieb:
Die Möglichkeit aus data die Bytegröße zu bestimmen existiert ja sicherlich nicht, oder?
Nein, in dem Fall ist data nur ein Zeiger, der dir leider nicht verrät, wie groß der Speicherbereich ist, auf den er zeigt.
-
Danke für die Hilfe!
-
~zero schrieb:
Also ZeroMemory steht in meinem Code ja oben, das würde als Kompletter Code nur so ausschauen
void __fastcall TForm1::Button3Click(TObject *Sender) { ZeroMemory(&data,sizeof(data)); }
Das hieße, dass data eine globale Variable ist, was schlechter Stil ist, nicht thread-safe ist, ...
-
~zero schrieb:
Die Möglichkeit aus data die Bytegröße zu bestimmen existiert ja sicherlich nicht, oder?
Wenn du MSVC/MinGW verwendest, geht
_msize(data)
für zuvor mit *alloc angeforderten Speicherbereich, ist aber kein ANSI C, wie das meiste, was du hier schreibst.