[C con Clase] Tamaño de Buffer

Steven Davidson srd4121 en njit.edu
Mie Jun 2 21:07:54 CEST 2010


Hola José Luis,

anonymous.mx wrote:
> Moises y Steven, gracias por la aportación.
>  
> Anexo el extracto del codigo. (no lo he compilado porque tenemos un 
> pequeño problema con el filesystem en donde se encuentran lo datos).
>  

Te comento algunos matices que he visto en tu código fuente, al igual 
que un error que cometiste.

>    tamanio = getfilesize(f1);
>    fseeko64 (f1, 3200+17-1, SEEK_SET);
>    fread (&int2, sizeof(int2), 1, f1);  
>    _si = entero2(int2)/1000000.;
>    fseeko64 (f1, 3200+21-1, SEEK_SET);
>    fread (&int2, sizeof(int2), 1, f1);  
>    _nsmp = entero2(int2);
>    fseeko64 (f1, 3200+25-1, SEEK_SET);

Veo que usas algunos valores literales. Sin embargo, estos valores 
parecen tener un significado especial que seguramente se refieran a un 
concepto. Cuando esto ocurre, sugiero definir constantes. Esto es,

const int COMIENZO_INFO = 3200;
...
fseeko64( f1, COMIENZO_INFO+17-1, SEEK_SET );

También sospecho que 17, 21, y 25 son conceptos especiales y por tanto 
deberían ser definidas con constantes.

>    fread (&int2, sizeof(int2), 1, f1);  
>    _frmt = entero2(int2);
>    if     (_frmt==3) _smpl=2;
>    else if(_frmt==6) _smpl=1;
>    else              _smpl=4;
>    // Tama#o de la traza (bytes)
>    _trl = 240+_nsmp*_smpl;
>    // Numero de trazas
>    _ntr=(tamanio-3600)/(_trl);
>    //Crear el buffer
>    unsigned char *_buffer = (unsigned char *) malloc( _ntr );
>    // Escribir el encabezado del SEGY
>    fseeko64 (f1, 0, SEEK_SET);
>    bytesLeidos = fread(_binhed, 1, sizeof(_binhed), f1);
>    fwrite(_binhed, 1, bytesLeidos, fs);
>    for (n=1;n<=_ntr;n++)

No veo que sea necesario ir de 1 a '_ntr', ya que siempre que uses 'n' 
lo haces de esta forma: 'n-1'. Por consiguiente, sugiero reescribir el 
bucle 'for' así:

for( n=0; n<_ntr; n++ )

Ahora puedes tratar 'n-1' como 'n' y así te ahorras unas cuantas restas 
en cada iteración.

>    {
>       fseeko64 (f1, 3600+((n-1)*_trl), SEEK_SET);
>       fread (&_trched, sizeof(_trched), 1, f1);
>      
>       int4[0]=_trched[17-1];
>       int4[1]=_trched[17-0];
>       int4[2]=_trched[17+1];
>       int4[3]=_trched[17+2];
>      
>       // Grabar el dato si el SP corresponde con el indicado en parametros.
>       if (SP==entero4(int4))

Sospecho que 'entero4' realiza alguna conversión. Sin embargo, no veo 
que tengas que crear otro array solamente con 4 elementos; posiblemente 
4 bytes. Simplemente usa '_trched'. Esto es,

entero4( &_trched[17-1] )

O de su forma equivalente:

entero4( _trched + 17-1 )

Esta función o posiblemente conversor de tipos aceptará un array de 4 
elementos. Esto es justo lo que las expresiones anteriores realiza.

>       {
>          fseeko64 (f1, 3600+((n-1)*_trl), SEEK_SET);
>          bytesLeidos = fread(_buffer, 1, sizeof(_buffer), f1);

Esto es un error. La expresión 'sizeof _buffer' resultará siempre en 4 
bytes, si se trata de una compilación para un sistema operativo de 32 
bits. Recuerda que ahora '_buffer' es un puntero y no un array estático.

La solución es indicar la cantidad máxima, '_ntr', que usaste en 
'malloc()'. Esto es,

bytesLeidos = fread( _buffer, 1, _ntr, f1 );

>          fwrite(_buffer, 1, bytesLeidos, fs);
>       }
>    }
>    // Liberar el buffer
>    free( _buffer );
>   
>    /* Cerramos el fichero */
>    fclose(f1);
>    fclose(fs);
> 


Espero que esto te ayude.

Steven




Más información sobre la lista de distribución Cconclase