Moin Daniel, Am Montag, 11. Oktober 2004 21:53 schrieb Daniel Lord:
On Fri, Oct 08, 2004 at 12:54:05AM +0200, Jan Trippler wrote: [...]
Warum eine Struktur, wenn Du nur ein Array aus *char benötigst?
Das diente nur der besseren Erweiterbarkeit. Eine Struktur benötigt an sich keinen Speicherplatz. Und da ich das Programm irgendwann evtl. noch um Zusatzfunktionen aufstocken wollte... Deshalb struct.
OK, das wollte ich hören ;-) [...]
Warum liest Du die gesamte Datei in den Speicher (und schlägst Dich mit malloc() und den damit verbundenen Risiken rum), nur um die maximale Anzahl von Signaturen zu ermitteln? Ich halte das für unnötig. Meine Version habe ich unten angehängt.
Es ging mir weniger um die maximale Anzahl von Signaturen als vielmehr darum langsame Plattenzugriffe zu minimieren. D.h. ich lese die Datei nur ein einziges mal von der Platte (Diskcache etc. hab ich nicht berücksichtigt) Wäre aber glaube ich interessant mal einen Vergleich zu haben was schneller ist malloc oder zweimal lesen. (mit diskcache fürchte ich fast; deine Lösung :)
Da möchte ich nicht drauf wetten, aber ich behaupte mal, dass es im Bereich bis mehrere 10.000 Einträge nicht sonderlich aufhält (ich lese die Datei ja meist auch nicht 2x bis zum Ende, sondern 1x komplett und dann nur bis zur gesuchten Signatur).
if ((sig[signatur].data = malloc(SIGLEN+1)) == NULL) { perror("malloc"); goto failed; } sig[signatur].data[0]=0x00;
while (fgets(tmp, SIGWIDTH, fd) != NULL) { if (emptyline(tmp) != 0) { strcat(sig[signatur].data,tmp); [...] Schlimmer: Du prüfst nicht, wie lang der Inhalt von .data bereits ist. Eine Signatur mit mehr als 6 Zeilen a 84 Zeichen würde wahrscheinlich einen Segmentation Fault bewirken, da in nicht initialisierten Speicher geschrieben wird.
Nein, malloc wird vorher immer ausgeführt. Die Signatur fällt später allerdings durchs Raster. [*]
Nein, das meine ich nicht. Du initialisierst mit SIGLEN+1, prüfst aber nicht, wieviele Zeilen Du an die aktuelle Signatur (also den .data-Speicher) anhängst. Da könnten 100 Zeilen je 80 Zeichen stehen, was weit über SIGLEN hinausgeht, Du hängst ungeprüft an .data an, wenn dazwischen keine Leerzeile kommt. Damit provozierst Du einen segfault, weil Du über den per malloc reservierten Bereich hinauskommst. Deine Größenprüfungen kommen ja erst nach dem Einlesen der kompletten Datei. [...]
/* make sure you don't get flamed :) */ if (strlen(sig[randnum].data) > SIGLEN) {
Wie soll das gehen? Du initialisierst doch .data nur mit SIGLEN+1 und wenn die Signatur länger ist, dann gibts oben einen Buffer Overflow. Also besser gleich oben abfangen.
[*] <- hier ist später
zu spät (s. o.) ;-)
Nein, es gibt keinen Overflow. Es wird weiterhin Speicher zugewiesen.
Nur eben evtl. zuwenig. [...]
Ja, nur hat mich das mit der Validierung gestört. Nach jedem Einfügen einer Signatur eine neue DB erstellen... Na gut, lässt sich auch mit ein bischen bash erledigen und ich denke ich werde wohl in die Richtung gehen.
Der Vorteil ist der, dass Du wahrscheinlich wesentlich öfter die Datei liest als sie zu ändern. Damit relativiert sich der Aufwand und Du kannst das Programm zur Signaturauswahl (welches wohl wesentlich öfter läuft als die Validierung) einfacher halten. Was dazu kommt: Beim Validieren kannst Du Dir Zeit lassen, dafür geht das Auslesen der Signatur dann deutlich schneller (ich würde mir z. B. in die erste Zeile der validierten Datei die Anzahl der Signaturen schreiben). Jan -- Linux-Quickies: http://www.jan-trippler.de PingoS: http://www.pingos.org TTS-HowTo: https://ssl.pingos.org/pingos/intern/ttshowto/rt.html