falla de segmentación memcpy en linux pero no os x
pointers segmentation-fault (4)
Cuando agrega 1 a un puntero p, no está agregando 1 byte, está agregando un tamaño de (p) bytes.
Entonces, en este caso, debe convertir el record
en un char*
antes de agregarlo. En este momento, record+500
realidad puntos 500 * 528 = 264,000 bytes fuera del record
.
Por supuesto, esto no explica por qué memcpy(buf, record+254, 1)
no segfault. Solo "suerte", supongo.
Estoy trabajando en la implementación de un sistema de archivos basado en registros para un archivo como proyecto de clase. Tengo una buena cantidad de trabajo en mi computadora portátil OS X de 64 bits, pero cuando intento ejecutar el código en las máquinas Linux de 32 bits del departamento de CS, obtengo un fallo seg.
La API que se proporciona permite escribir DISK_SECTOR_SIZE (512) bytes a la vez. Nuestro registro de registro consta de los 512 bytes que el usuario desea escribir, así como algunos metadatos (en qué sector desea escribir, el tipo de operación, etc.).
Con todo, el tamaño del objeto "registro" es de 528 bytes, lo que significa que cada registro de registro abarca 2 sectores en el disco.
El primer registro escribe 0-512 en el sector 0 y 0-15 en el sector 1. El segundo registro escribe 16-512 en el sector 1 y 0-31 en el sector 2. El tercer registro escribe 32-512 en el sector 2, y 0-47 en el sector 3. ETC.
Entonces, lo que hago es leer los dos sectores que voy a modificar en 2 búferes recién asignados, copiando desde el registro en buf1 + el desplazamiento calculado para 512 bytes de compensación. Esto funciona correctamente en ambas máquinas.
Sin embargo, la segunda memcpy falla. Específicamente, "registrar + DISK_SECTOR_SIZE-offset" en los códigos de segfeults siguientes, pero solo en la máquina de Linux. Ejecutar algunas pruebas al azar, se vuelve más curioso. La máquina Linux informa que sizeof (Record) es 528. Por lo tanto, si intenté memcpy desde el registro + 500 en buf por 1 byte, no debería haber un problema.
De hecho, el mayor desplazamiento que puedo obtener del registro es 254. Es decir, memcpy (buf1, record + 254, 1) funciona, pero memcpy (buf1, grabar + 255, 1) segfaults.
¿Alguien sabe lo que me estoy perdiendo?
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));
Intente ejecutar su código de Linux bajo valgrind
, eso debería llevarlo directamente a la causa raíz del problema.
record + DISK_SECTOR_SIZE-offset es su problema. registro + 1 no da y dirección de registro + 1.
Le da a usted y la dirección de registro + 1 * tamaño de (registro). (Cuando incremente o disminuya un puntero, ingresará los múltiplos del tipo de datos que usa. Simplemente escriba su puntero de registro de la siguiente manera: (byte *) record + DISK_SECTOR_SIZE-offset. Eso explicaría el error de segmentación dado que el registro es al menos DISK_SECTOR_SIZE long .
record+BLAH
significa, cuando se traduce en código máquina: agregue BLAH*sizeof(Record)
a la dirección record
.
Entonces record+500
no es 500 bytes del record
; está a 500 * 528 = 264000 bytes del record
.