Frage

Ich arbeite ein Protokoll basiertes Dateisystem für eine Datei als Klasse-Projekt zur Implementierung. Ich habe eine gute Menge davon auf meinem 64-Bit-OS X Laptop arbeiten, aber wenn ich versuche, den Code auf der CS-Abteilung 32-Bit-Linux-Rechner zu laufen, ich seg Fehler erhalten.

Die API uns gegeben sind erlaubt das Schreiben DISK_SECTOR_SIZE (512) Bytes zu einer Zeit. Unser Protokolldatensatz besteht aus den 512 Bytes des Benutzer sowie einige Metadaten schreiben will (den Sektor er schreiben will, die Art der Operation, usw.).

Alles in allem die Größe des „record“ Objekt ist 528 Bytes, die jeweils Protokolldatensatz Spannweiten 2 Sektoren auf der Platte bedeutet.

Der erste Datensatz schreibt 0-512 auf Sektor 0 und 0-15 auf Sektor 1. Der zweite Datensatz schreibt 16-512 auf dem Sektor 1 und 0-31 auf Sektor 2. Der dritte Eintrag schreibt 32-512 auf Sektor 2 und 0-47 auf sector 3. ETC.

Also, was ich tun ist, die zwei Sektoren gelesen werde ich in zwei frisch zugewiesenen Puffer werden zu modifizieren, kopiert auf Rekord beginnend in buf1 + die Offset berechnet für 512-Offset Bytes. Dies funktioniert korrekt auf beiden Maschinen.

schlägt jedoch fehl, die zweite Memcpy. Genauer gesagt, "record + DISK_SECTOR_SIZE-offset" in der unten angegebenen Code segfaults, aber nur auf der Linux-Maschine. Laufen einige zufällige Tests, wird es mehr neugierig. Die Linux-Rechner Berichte sizeof (Record) 528. Daher ist, wenn ich von Rekord + 500 in buf für 1 Byte bis MEMCPY versucht, es sollte kein Problem haben.

In der Tat, der größte Versatz ich von Rekord bekommen kann, ist 254. Das heißt, memcpy (buf1, Rekord + 254, 1) funktioniert, aber memcpy (buf1, Rekord + 255, 1) segfaults.

Wer weiß, was ich bin fehlt?

Record *record = malloc(sizeof(Record));
record->tid = tid;
record->opType = OP_WRITE;
record->opArg = sector;
int i;
for (i = 0; i < DISK_SECTOR_SIZE; i++) {
  record->data[i] = buf[i]; // *buf is passed into this function
}

char* buf1 = malloc(DISK_SECTOR_SIZE);
char* buf2 = malloc(DISK_SECTOR_SIZE);

d_read(ad->disk, ad->curLogSector, buf1);  // API to read a specified sector into a buffer
d_read(ad->disk, ad->curLogSector+1, buf2);

memcpy(buf1+offset, record, DISK_SECTOR_SIZE-offset);
memcpy(buf2, record+DISK_SECTOR_SIZE-offset, offset+sizeof(Record)-sizeof(record->data));
War es hilfreich?

Lösung

Wenn Sie 1 auf einen Zeiger p hinzufügen, werden Sie nicht die Zugabe von 1 Byte, die Sie hinzufügen sizeof (p) Bytes.

Also in diesem Fall, müssen Sie Guss record zu einem char* vor ihm hinzufügen. Gerade jetzt record+500 Punkte tatsächlich 500 * 528 = 264.000 Bytes weg von record.

Natürlich ist dies nicht erklären, warum memcpy(buf, record+254, 1) segfault nicht. Nur "Glück", schätze ich.

Andere Tipps

record+BLAH Mittel, wenn sie in Maschinencode übersetzt. Add BLAH*sizeof(Record) an die Adresse in record

So record+500 ist nicht 500 Bytes von record; es ist 500 * 528 = 264000 Bytes weg von record.

Versuchen Sie Ihren Linux-Code unter valgrind läuft -. Das sollte man direkt auf die Ursache des Problems nehmen

Datensatz + DISK_SECTOR_SIZE-Offset ist Ihr Problem. Rekord + 1 doesnt geben und Anschrift des Rekords + 1.

Es gibt Ihnen und Anschrift des Rekord + 1 * sizeof (Rekord). (Wenn Sie erhöhen oder einen Zeiger oder vermindern, die Schritte in Vielfachen der Daten geben Sie Ihre Verwendung nur Typumwandlung Ihre Datensatzzeiger wie folgt:. (Byte *) record + DISK_SECTOR_SIZE-Offset Das würde die Segmentierungsfehler erklären, da Rekord zumindest DISK_SECTOR_SIZE ist lang. .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top