Virtuelles File System in C schreiben
-
LordXearo schrieb:
Ich dachte mir durch die "+6" hab ich mir genug Speicher für den Pfad und die Endung reserviert. Könnte mich da jemand aufklären?
Xearo
Nein, das ist nicht genug, du brauchst noch ein Platz für den 0-Terminator.
-
Autsch...ja klar. So oft gelesen und trotzdem macht man es manchmal falsch.
Nun scheint es zu klappen, bekomme jedenfalls keinen Fehler mehr beimAufruf von "free()".
Noch eine Frage...
Ich habe Zeilen mit unterschiedlichen längen. Ich würde diese dann wiederverwenden bzw. überschreiben. Wenn die neue Zeile länger als die alte Zeile ist, überschreibt mir das Programm natürlich noch die nächste Zeile mit.
Gibt es da eine Möglichkeit das zu ändern, OHNE, eine weitere Datei anzulegen?
-
Schon wieder ein Problem beim freigeben vom Speicher. Diesmal kann ich mir keinen reim drauf machen.
Ich reserviere mir erstmal Speicher
uint64_t *Anzahl = (uint64_t *) malloc (sizeof(uint64_t) );
Später wird der Speicherplatz immer um 1 erhöht.
realloc(Anzahl ,( (AnzDateien) * sizeof(uint64_t) ) );
Während der Speicherplatz erhöhrt wird, werden auch die Stellen beschrieben.
Anzahl[AnzDateien-1] = _strtoi64(TeilString,NULL,10);
Wenn ich mit der Verarbeitung (die korrekt ausgeführt wird) fertig bin, möchte ich den Speicher freigeben free(), womit mir das Programm abschmiert.
Ich kann mir das nicht erklären.
-
Hab es doch geschafft.
Hab mir den Befehl "realloc" wohl von einer schlechten Quelle angeschaut.
Nun sieht es so aus:
Anzal = (uint64_t *) realloc(Anzahl,( (AnzDateien) * sizeof(uint64_t) ) );
Ist das eigentlich C Konform?
Bzw. ist das so sinnvoll oder mache ich es unnötig schwer?
-
LordXearo schrieb:
Hab mir den Befehl "realloc" wohl von einer schlechten Quelle angeschaut.
Dann sei sicher, dass du nur gute Quellen benutzt. Bekannt schlechte Quellen sind leider die meisten (original) deutschsprachigen Bücher und ganz allgemein Internettutorials.
Nun sieht es so aus:
Anzal = (uint64_t *) realloc(Anzahl,( (AnzDateien) * sizeof(uint64_t) ) );
Ist das eigentlich C Konform?
Streng genommen: Ja.
Bzw. ist das so sinnvoll oder mache ich es unnötig schwer?
Da ist vieles dran schlecht:
-Rechtschreibung
-unnötiger Cast
-sizeof mit festem Typ
-keine Behandlung eines fehlgeschlagenen reallocsDie ersten drei korrigiert:
Anzahl = realloc(Anzahl, AnzDateien * sizeof(*Anzahl));
Der letzte Punkt ist subtiler aber wichtig. Schlägt realloc fehl, so wird 0 zurück gegeben. Aber worauf Anzahl zeigt wird nicht freigegeben! In diesem Fall wäre der Wert des Zeigers Anzahl mit 0 überschrieben und der ursprünglich referenzierte Speicher unwiederbringlich verloren. Ganz schlecht.
Eine oberflächliche Behandlung des Problems wäre ein temporärer Zwischenwert:
uint64_t* temp = realloc(Anzahl, AnzDateien * sizeof(*Anzahl)); if (temp) Anzahl = temp; else Fehlerbehandlung;
Das ist äußerst unschön und auch temporäre Zwischenwerte sind oft ein Zeichen von ungünstiger Programmierung. Schöner wäre eine Abkapselung der gesamten Speicherverwaltung. Ist aber im Moment wohl noch ein zu fortgeschrittener Themenkomplex für dich.
-
Danke für deine Hilfe Seppj.
ich mache noch eine Fehlerbehandlung, ich prüfe ob der Speicher reserviert werden konnte.
if ( Speicher == NULL) ...
Wenn ich das (uint_64t
vor malloc oder realloc weglasse, mekert visual studio.
Freu mich schon wenn ich soweit bin, das ganze auch in gcc zum laufen zu bekommen....Sorry bin gerad kurz angebunden.
Erstmal danke.
-
LordXearo schrieb:
Wenn ich das (uint_64t
vor malloc oder realloc weglasse, mekert visual studio.
Wenn du meinst, es gäbe eine Fehlermeldung bei der Übersetzung, dann benutzt du einen C++-Compiler. Tu das nicht.
Wenn du meinst, dass deine IDE meinst, das wäre falsch, dann liegt das da dran, dass VS eine IDE für C++ ist und der Hersteller ihm keinen Modus für C spendiert hat. Da kann man nichts machen, außer es zu ignorieren, da man es besser weiß oder kein VS für C zu benutzen.
-
Hallo, auch ich bin an der gleichen Aufgabe dran und habe ein ähnliches Problem.
Das mit dem malloc funktioniert bei mir aber das Problem ist wie bekomme ich es hin, den Pfad aufzuteilen?
Also in 2 Pfade, damir ich sie dann einzeln ergänzen kann?
-
Also wenn ich zB jetzt in Java wäre:
pfad1 = pfad
pfad2 = pfadstore = pfad1 + store
structure = pfad2 + structureoder so in der Art
-
SeppJ schrieb:
Wenn du meinst, dass deine IDE meinst, das wäre falsch, dann liegt das da dran, dass VS eine IDE für C++ ist und der Hersteller ihm keinen Modus für C spendiert hat.
Das stimmt so nicht.
Visual Studio unterstützt zumindest C89, die Dateien müssen dafür aber die Endung .c haben (oder man stellt die Kompilierung explizit auf C um).
TagBoz schrieb:
aber das Problem ist wie bekomme ich es hin, den Pfad aufzuteilen?
Schau dir mal die C-Stringverarbeitungsfunktionen an.
-
TagBoz schrieb:
Also wenn ich zB jetzt in Java wäre:
pfad1 = pfad
pfad2 = pfadstore = pfad1 + store
structure = pfad2 + structureoder so in der Art
Hol dir den Speicher mit malloc für beide Pfade.
Dann den Pfad mit strcpy in den reservierten Speicher schreiben.
Als letztes noch mit strcat die Dateiendungen hinzufügen.Ich schau mal, wie ich VS 2012 auf C umstellen kann.
-
Unter Projekteigenschaften / C/C++ / Komplilierungsart = "/TC".
-
Das ist ja grauenvoll....dann wird es im C98 standard kompiliert, d.h. sowas
for(int i; ... ) ist nicht mehr gültig...
Un wenn ich den Typcast bei malloc weglasse mekert er trotzdem.....
Hilft wohl nichts als das Programm nochmal separat für gcc zu bearbeiten.
-
C'ler schrieb:
SeppJ schrieb:
Wenn du meinst, dass deine IDE meinst, das wäre falsch, dann liegt das da dran, dass VS eine IDE für C++ ist und der Hersteller ihm keinen Modus für C spendiert hat.
Das stimmt so nicht.
Visual Studio unterstützt zumindest C89, die Dateien müssen dafür aber die Endung .c haben (oder man stellt die Kompilierung explizit auf C um).
Ich weiß, dass der Compiler C89 kann, das habe ich doch im Satz davor gesagt. Ich meinte, dass der Editor Sachen als falsch ankringelt, die in C richtig sind, in C++ aber falsch.
Da ich VS nicht benutze kann ich beides nur weitergeben aus anderen Quellen, aber ich vertraue den häufigen Beschwerden im Forum darüber eher als dieser einen einzigen Meldung des Gegenteils, von der ich mal annehme, dass du dich auf den Compiler bezogen hast.
-
C'ler schrieb:
SeppJ schrieb:
Wenn du meinst, dass deine IDE meinst, das wäre falsch, dann liegt das da dran, dass VS eine IDE für C++ ist und der Hersteller ihm keinen Modus für C spendiert hat.
Das stimmt so nicht.
Visual Studio unterstützt zumindest C89, die Dateien müssen dafür aber die Endung .c haben (oder man stellt die Kompilierung explizit auf C um).
Gemeint war hier natürlich der IDE-Modus für C; und was ist der IDE-Modus?
Richtig, Intellisense.
Der Compiler selbst (cl.exe) kann natürlich anhand der Option /TC oder anhand der Dateiendung *.c erkennen, was gemeint ist und macht das dann auch so.
Der Haken ist aber, dass die Default-Einstellung der IDE VisualStudio eben nicht C sondern C++ ist, und für C gibt es in VS kein Intellisense, da kannst du die Compiler-Optionen korrekt auf C gestellt haben, es nützt alles nichts;
"fehlende" Casts bei malloc usw. werden angemahnt.
-
Das defragmentieren dieses vfs macht mich fertig....
Ich habe noch keine Vorstellung wie ich es genau anstellen soll. Erstmal habe ich mir vorgenommen, zu jeder Datei, alle Blöcke zuzordnen, die diese Datei im Store belegt. Habe also bereits ein zwei-dimensionales dynamisches Array angelegt und alles richtig zugeordnet.
Nun denke ich, dass das mit Großen Dateien nicht hinhauen wird.
Angenommen ich habe 100 Dateien (Zeilen) und die größte Datei belegt 10.000 Blöcke, also habe ich dann 10.000 Spalten. Jeder dieser werte ist 64Bit lang.Das würde einen immensen Speicherplatz benötigen.
Eine Datei die 10.000 Blöcke belegt, bei der jeder Block eine größe von 4096Byte hat, wäre auch gerade mal ~41MB groß.Also erstmal alles in den Speicherladen fällt schonmal flach, hat jemand einen Tipp für mich?
-
Hallo,
obwohl das Anlegen bei mir mittlerweile funktioniert gibt valgrind immer noch einige Fehler aus und ich habe einfach keine Vorstellung wie ich diese beseitigen bzw. verstehe nochnichtmal die Fehlerbeschreibung wirklich. Deswegen bitte ich nochmal um eure Hilfe:
Also mein Code für das CREATE sieht so aus:int create(char *pfadVFS, char *groesseBlockString, char *anzahlBloeckeString) { // 0 Kommando wurde fehlerfrei ausgeführt // 1 Anlegen des VFS war nicht möglich (Aus Gründen, die // das Hostsystem verursacht hat) // 3 Ein VFS mit dem gegebenen Namen existiert bereits int groesseBlock, anzahlBloecke; int rueckgabe = 0; char *pfadStore; char *pfadStructure; char *pfadStoreErgaenzung = ".store"; char *pfadStructureErgaenzung = ".structure"; int laenge; laenge = strlen(pfadVFS); pfadStore = (char*) malloc(laenge + 7); pfadStructure = (char*) malloc(laenge + 10); strcpy(pfadStore, pfadVFS); strcpy(pfadStructure, pfadVFS); strcat(pfadStore, pfadStoreErgaenzung); strcat(pfadStructure, pfadStructureErgaenzung); rueckgabe = validateCreate(pfadStore, pfadStructure, groesseBlockString, anzahlBloeckeString); if(rueckgabe != 0) { return rueckgabe; } groesseBlock = atoi(groesseBlockString); anzahlBloecke = atoi(anzahlBloeckeString); rueckgabe = storeDateiErzeugen(pfadStore, groesseBlock, anzahlBloecke); if(rueckgabe !=0) { return rueckgabe; } rueckgabe = structureDateiErzeugen(pfadStructure, groesseBlock, anzahlBloecke); if(rueckgabe !=0) { return rueckgabe; } free(pfadStore); free(pfadStructure); return 0; }
Die valgrind-Hinweise sehen so aus:
==6766== Memcheck, a memory error detector ==6766== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==6766== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==6766== Command: /tmp/number-a.out /tmp/testarchiv create 4096 40 ==6766== ==6766== Invalid write of size 1 ==6766== at 0x48DBDA7: strcat (mc_replace_strmem.c:176) ==6766== by 0x804A9EB: create (1376505601.c:1293) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== Address 0x6d1f09a is 0 bytes after a block of size 34 alloc'd ==6766== at 0x48DAF50: malloc (vg_replace_malloc.c:236) ==6766== by 0x804A9A0: create (1376505601.c:1287) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== ==6766== Invalid read of size 1 ==6766== at 0x48DC0C3: strlen (mc_replace_strmem.c:282) ==6766== by 0x49515F1: vfprintf (vfprintf.c:1617) ==6766== by 0x495822F: printf (printf.c:35) ==6766== by 0x804AA13: create (1376505601.c:1295) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== Address 0x6d1f09a is 0 bytes after a block of size 34 alloc'd ==6766== at 0x48DAF50: malloc (vg_replace_malloc.c:236) ==6766== by 0x804A9A0: create (1376505601.c:1287) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== ==6766== Syscall param open(filename) points to unaddressable byte(s) ==6766== at 0x49CD97E: __open_nocancel (syscall-template.S:82) ==6766== by 0x4978897: _IO_file_fopen@@GLIBC_2.1 (fileops.c:336) ==6766== by 0x496CB9C: __fopen_internal (iofopen.c:93) ==6766== by 0x496CBFB: fopen@@GLIBC_2.1 (iofopen.c:107) ==6766== by 0x804AB20: validateCreate (1376505601.c:1343) ==6766== by 0x804AA33: create (1376505601.c:1299) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== Address 0x6d1f09a is 0 bytes after a block of size 34 alloc'd ==6766== at 0x48DAF50: malloc (vg_replace_malloc.c:236) ==6766== by 0x804A9A0: create (1376505601.c:1287) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== ==6766== ==6766== HEAP SUMMARY: ==6766== in use at exit: 65 bytes in 2 blocks ==6766== total heap usage: 4 allocs, 2 frees, 769 bytes allocated ==6766== ==6766== 31 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==6766== at 0x48DAF50: malloc (vg_replace_malloc.c:236) ==6766== by 0x804A98F: create (1376505601.c:1286) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== ==6766== 34 bytes in 1 blocks are definitely lost in loss record 2 of 2 ==6766== at 0x48DAF50: malloc (vg_replace_malloc.c:236) ==6766== by 0x804A9A0: create (1376505601.c:1287) ==6766== by 0x804AEED: main (1376505601.c:1468) ==6766== ==6766== LEAK SUMMARY: ==6766== definitely lost: 65 bytes in 2 blocks ==6766== indirectly lost: 0 bytes in 0 blocks ==6766== possibly lost: 0 bytes in 0 blocks ==6766== still reachable: 0 bytes in 0 blocks ==6766== suppressed: 0 bytes in 0 blocks ==6766== ==6766== For counts of detected and suppressed errors, rerun with: -v ==6766== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 15 from 8)
-
Vielleicht mal die erste Frage: Warum steht da, dass ich 4mal malloc und 2mal free benutze. Das scheint ein Problem zu sein. Aber ich benutze doch nur 2mal malloc?
-
Viele Pfade führen aus deiner Funktion, bei denen der Speicher nicht korrekt freigegeben wird. Weiterhin schreibst du irgendwo hinter ein von dir reserviertes Feld, was ebenfalls ein sehr ernstes Problem ist. Die Zeilennummern sagen dir, wo.
-
Du zeigst nicht den ganzen Code.
Außerdem kannst du auch nicht rechnen, +10 ist zu klein.