Virtuelles File System in C schreiben
-
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.
-
Es sollen auch 64Bit lange Datentypen verwendet werden, weil das Programm auch mit Gigabyte bzw. Terrabyte großen Dateien klar kommen soll.
-
Wutz schrieb:
Außerdem kannst du auch nicht rechnen, +10 ist zu klein.
Ahh, ich kann doch noch zählen :p . Ich hatte schon gedacht, so ein dummer Fehler kann's nicht sein.
Daher benutzt man besser eine narrensichere Methode, die die nötige Größe bestimmt, anstatt dass man selber zählt. Dann kann man das Literal später auch noch ändern und es funktioniert trotzdem noch.
-
Wutz schrieb:
Du zeigst nicht den ganzen Code.
Außerdem kannst du auch nicht rechnen, +10 ist zu klein.Aha "structure" = 9 + 1 für das Ende-Zeichen = 10
Was ist daran falsch?
-
SeppJ schrieb:
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.
Wie meinst du das? Ich reserviere mir doch direkt den ganzen Speicher den ich brauche...und ich habe überprüft ob die Pfade richtig zusammengebaut werden.
-
C_Mond schrieb:
Wutz schrieb:
Du zeigst nicht den ganzen Code.
Außerdem kannst du auch nicht rechnen, +10 ist zu klein.Aha "structure" = 9 + 1 für das Ende-Zeichen = 10
Was ist daran falsch?Aber da steht nicht "structure". Guck noch mal genau hin. Und bevor du das jetzt einfach zu 11 änderst, denkst du mal daêüber nach, wie du das besser machen könntest, ohne magic numbers. Und damit meine ich nicht
const int length = 11;
.
-
C_Mond schrieb:
SeppJ schrieb:
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.
Wie meinst du das? Ich reserviere mir doch direkt den ganzen Speicher den ich brauche...und ich habe überprüft ob die Pfade richtig zusammengebaut werden.
Ja, du reservierst den Speicher. Das ist ja das Problem, denn er wird nicht mehr unbedingt frei gegeben. Bloß in einem von vier Fällen, die ich sehe. Und da zähle ich mögliche, mir unbekannte, Nebeneffekte von storeDateiErzeugen nicht mit.
Ich glaube, dir täte mal etwas Strukturierung gut:
http://en.wikipedia.org/wiki/Structured_programming
Dogmatisches Anhängen an strukturierter Programmierung ist zwar etwas aus der Mode, aber das liegt nicht da dran, dass es schlecht wäre, sondern da dran, dass es praktisch jeder so beigebracht bekommen hat und ohnehin immerzu benutzt und man dadurch die paar Ausnahmen deutlich sieht, in denen es nicht die beste Vorgehensweise ist.
Du hast derzeit sehr viele verschiedene Ausführungspfade und scheinst selber total den Überblick verloren zu haben, wenn du mit meinem Hinweis nichts anfangen konntest.
-
Okay ich bin nun mal ein Neuling sonst wäre ich ja nicht hier um Hilfe zu suchen.
Den Code fand ich bis jetzt eigentlich übersichtlich.Könntest du mir einfach mal die 4 Fälle nennen die du siehst?
-
Alle return, die vor den free stehen.
-
Dankeschön euch allen damit kann ich weiterarbeiten.
-
Ich komm mit der defragmentierung einfach nicht zurecht, bzw. eine Vorgehensweise/Algorithmus hätte ich schon, aber programmiert bekomme ich es nicht.
Meine "FAT"
Datei1,1,3,6,7
Datei2,2
Datei3,8,9,10
Datei4,4,11,12So sieht die Datei aus. Neue Dateien werden schon automatisch in aufsteigender Reihenfolge geschrieben. Dazwischen können natürlich lücken entstehen, wenn Dateien gelöscht werden.
Nun meine Überlegung.... Ich weiss das die Dateien in der FAT 11 Blöcke belegen. Also brauche ich, um eine defragmentierte FAT zu erhalten, die Blöcke 0-10.
Ich fange mit dem niedrigsten Block an (also 0). Dabei schaue ich, ob der aktuell bearbeitete Block der Block 0 ist oder ob dieser Block bereits bei einer anderen Datei in Benutzung ist. Daraus ergibt sich folgendes Bild...
Datei1,0,3,6,7
....
Problematisch wird es dann erst bei Block 2, da der schon vergeben ist. Dafür muss aber einfach, das ganze Szenario 2 mal durchlaufen werden.
Erster durchgang ergibt dann:
Datei1,0,1,3,5
Datei2,6
Datei3,7,8,9
Datei4,10,11,12
Zweiter Durchgang (Nun ist block 2 frei):
Datei1,0,1,2,3
Datei2,4
Datei3,5,6,7
Datei4,8,9,10Eigentlich relativ simpel. Aber jetzt in der Datei hin und her zu springen, mit 3 oder 4 verschachtelten Schleifen, mit fgets, strtok, ftell und was man noch alles braucht wird es mir einfach zu viel.
Übersehe ich vielleicht einen einfachen weg die Datei auseinander zu nehmen um meine Bedingungen zu prüfen?
-
Gerade kam mir noch ein guter Einfall....ohne die Datei müsig auseinander zunehmen mit strtok, müste es ja reichen jede zeile mit strstr(Buffer,",3,") zu durchsuchen, um festzustellen ob ein Block in Benutzung ist....
-
Hallo, ich denke ich konnte bis jetzt alle Speicherleckfehler erfolgreich beheben. Dankeschön.
Im Moment habe ich folgendes Problem. An einigen Stellen überprüfe ich, ob es eine Datei schon gibt mit folgendem code
FILE *datei; String* pfad; datei = fopen(pfad, "r+"); if(datei == NULL) { printf("Datei ist NULL"); } else { print("Die Datei ist nicht NULL"); }
Bei mir auf dem PC (Windows oder Linux) funktioniert das auch. Habe es auch schon gedebuggt. Aber sobald ich die Datei an das automatische Prüfsystem schicke ist die Datei nicht NULL. Leider kann ich dort nicht debuggen aber meine Logausgaben sagen, dass er auch in die falsche Bedingung läuft.
Das verstehe ich einfach nicht. Kann es sein, dass das Programm auf einer anderen Linuxmaschine anders reagiert???
-
Äh natürlich nicht String* sondern char*
-
Das ist eine Programmieraufgabe für Informatik aus dem aktuellen Sommersemester der Heinrich Heine Universität Düsseldorf Sommersemester2013. Es scheint du hast in den Vorlesungen nicht aufgepasst.