[C con Clase] Que problemas puede causar memcpy al introducir un buffer de datos en un struct

José Luis Torre joseluistorrehernandez en gmail.com
Jue Oct 25 00:06:14 CEST 2012


Marta:

Muéstrame un ejemplo de la salida del programa KLEE y te comentaré cómo
puedes leerlo desde tu programa.

Saludos
José Luis


El 24 de octubre de 2012 22:26, marta vic <marvicekl en gmail.com> escribió:

> Muchisimas gracias por las respuestas
>
> La cuestion es que yo recibo ese valor de otro programa y lo tengo que
> introducir en un programa c para inicializar la estructura,
> el programa (KLEE) me da directamente esa informacion y la estructura
> siempre sera la adecuada, pro qeu es la misma estructura que klee ha
> analizado y me ha dado ese valor hexadecimal.
>
> por lo tanto necesito una forma de re introducir el valor en la estructura
> y no creo que con memset pueda hacerlo (aunque voy a mirar si tengo alguna
> alternativa)
>
> Los valores de la salida seran distintos a 0, ya que lo que hace klee es
> generar valores para las estructuras pero no es capaz de separarlos por
> campos de ahi el problema
>
> muchisimas gracias
> mirare la documentacion  que me aconsejas
>
> Un saludo
> El 8 de octubre de 2012 12:03, Salvador Pozo <salvador en conclase.net>escribió:
>
> El pasado 2012-10-07 22:10:00, marta vic escribió:
>>
>> mv> Hola
>> mv> Tengo una duda, y busco mas lugares donde pueda acceder a
>> explicaciones o
>> mv> documentacion que una explicacion concreta,
>> mv> me gustaria definir los problemas que se pueden encontrar al intentar
>> mv> ejecutar un codigo como este:
>> mv> memcpy(&estructura1,"\x00\x00\x00\x00\x00\x00\x00\x00",8);
>> mv> en este caso
>> mv> estructura1{
>> mv>     int a;
>> mv>     int b;
>> mv> }
>>
>> Hola:
>>
>> Antes de ver qué problemas puede haber en este mecanismo, comentar que
>> existen soluciones mejores para hacer lo que se pretende.
>>
>> En la misma biblioteca que memcpy existe otra función, memset, que está
>> diseñada específicamente para esa tarea.
>>
>> En tu caso concreto, podría usarse de este modo:
>>
>> ----8<------
>> struct {
>>     int a;
>>     int b;
>> } estructura1;
>>
>> memset(&estructura1,0,sizeof(structura1));
>> ----8<------
>>
>> Esto tiene algunas ventajas evidentes:
>> 1) No necesitas una cadena de ceros de longitud arbitraria, ya que usamos
>> un único valor de tipo int, que se usará como un byte (un unsigned char).
>> 2) No tenemos que usar una constante como tamaño de la estructura, en su
>> lugar usamos en operador sizeof, que nos da el tamaño exacto de la
>> estructura, independientemente de la arquitectura y de la alineación de
>> bytes usada.
>>
>> Respondiendo a tu pregunta, ahora no puedo decirte un lugar donde puedas
>> encontrar información sobre ese tema, sobre todo, porque no sé si existe
>> algo tan concreto.
>>
>> Los problemas son, entre otros, los que ha indicado José Luis:
>>
>> - Dependiendo de la plataforma y del compilador, los valores enteros
>> pueden tener distintos tamaños. En general, el tamaño de una estructura
>> estará determinado por el tamaño de cada uno de sus componentes, y en C ese
>> tamaño no está definido, salvo que el de int es mayor o igual que char, y
>> el de long int mayor o igual que int. (
>> http://c.conclase.net/curso/index.php?cap=002#inicio)
>>
>> - Otro problema es el de alineación de las variables en memoria. A
>> menudo, para mejorar la eficacia de los procesadores a la hora de acceder a
>> memoria, las direcciones de las variables pueden ser múltiplos de 2, de 4 o
>> de 8, dependiendo del tamaño de la palabra del microprocesador.
>> (http://c.conclase.net/curso/index.php?cap=011b#inicio)
>>
>> Por ejemplo, en esta estructura:
>> struct A {
>>    int x;
>>    char a;
>>    int y;
>>    char b;
>> };
>>
>> Si el alineamiento es de cuatro bytes, las posiciones de memoria de cada
>> elemento del array no serán consecutivas:
>> 0-3: x
>> 4: a
>> 5-7: libre
>> 8-11: y
>> 12: b
>> 13-15: libre
>>
>> De este modo, una estructura que debería ocupar 10 bytes, en realidad
>> ocupa 16.
>>
>> Es más, el tamaño final puede depender del orden en que se declaran los
>> elementos de la estructura, y de si se activa o no el alineamiento de bytes.
>>
>> - El problema con el formato Big Endian o Little Endian, en el caso
>> concreto de inicializar con ceros, no tiene importancia. Otro tema sería si
>> los valores iniciales no fueran nulos.
>>
>> - Por último, los problemas son casi iguales si se trata de arrays o
>> estructuras. En los dos casos nos afecta la arquitectura y el problema del
>> alineamiento de bytes.
>>
>> En cuanto a soluciones, arriba te he comentado la que se suele usar en C,
>> que consiste en utilizar la función memset.
>>
>> En C++ es preferible usar constructores, al menos en el caso de
>> estructuras, ya que para los arrays puede interesar más usar memset también.
>>
>> En general, no es buena idea que el programador haga las cuentas si puede
>> hacer que las haga el compilador. Para hacer las cuentas a mano, como en tu
>> ejemplo, debemos asumir el tamaño de las variables y cierta alineación,
>> pero eso hace que el programa no sea transportable, y no podemos garantizar
>> que funcione correctamente si se compila en otra plataforma, con otro
>> sistema operativo o con otro compilador.
>>
>> Seguramente encuentres documentación en la red haciendo consultas con:
>> memcpy gibendian
>> memcpy alineamiento bytes
>> memcpy plataformas
>>
>> Suerte, y hasta pronto.
>>
>> --
>> Salvador Pozo (Administrador)
>> mailto:salvador en conclase.net
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.net
>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>



-- 
José Luis Torre
ww.ehu.es
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20121025/04e85608/attachment.html>


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