C/Visual C - Como copiar memoria

   
Vista:

Como copiar memoria

Publicado por jaldonfer (31 intervenciones) el 02/12/2014 00:55:08
Hola:

Necesito ayuda.

Necesito transladar memoria de una esctructura a un string byte a byte, pero no lo consigo.

Tengo la siguiente estructura:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct str_a {
 
char a;
char b;
char c[16];
}
 
//Decklarar variables
struct str_a v_01 = {0}
char v_string[256] = "";
 
//Asignar valores a variables
v_01.a = '9';
v_01.b = '1';
strcat(v_01.c, "TEST");


¿ COMO COPIO LOS 18 BYTES DE LA ESTRUCTURA v_01 a v_string ?

Lo que quiero conseguir es que el valor de v_string sea "91TEST". He hecho varias pruebas con strcat, strncat, y memcpy, pero no he logrado que me funcione correctamente.

¿ Hay alguna funcion memcat ó algo por el estilo ?

Gracias por su ayuda


Saludos
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Como copiar memoria

Publicado por Capitan Kirk capitan.kirk09@gmail.com (94 intervenciones) el 02/12/2014 09:07:16
Tienes tres opciones, dependiendo de lo que quieras hacer.

La primera es declarar una unión. Con la unión, lo que haces es que la estructura y el string compartan la misma zona de memoria. Lo que modifiques en uno se verá reflejado en el otro. Por ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
struct str_a
{
	char	a;
	char	b;
	char	c[16];
};
 
union uni
{
	struct str_a	v_01;
	char			v_string[256];
};
 
int main (void)
{
	union uni MiUni;
 
	/* Cargamos valores en los miembros de la unión a través de la estructura str_a */
	MiUni.v_01.a = '9';
	MiUni.v_01.b = '1';
	strcpy(MiUni.v_01.c, "TEST");
 
	/* Mostramos el resultado a través de la cadena de caracteres
	printf("Resultado: %s\n", MiUni.v_string);

	return 0;
}

La segunda es copiar los bytes de la estructura, accediendo a ella a través de un puntero:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
struct str_a
{
	char	a;
	char	b;
	char	c[16];
};
 
char	v_string[256];
 
int main (void)
{
	struct str_a v_01;
	int	i;
	char *ptr;
 
	v_01.a = '9';
	v_01.b = '1';
	strcpy(v_01.c, "TEST");
	ptr = (char *)&v_01;
 
	for (i=0; i<sizeof(v_01); i++)
	{
		v_string[i] = *ptr;
		ptr++;
	}
	printf("Resultado: %s\n", v_string);
	return 0;
}

La tercera opción es que esto último te lo hace la función memcpy(), que está en <string.h>. Su prototipo es:

1
void *memcpy (void *s1, void *s2, int n);

que copia n bytes del objeto apuntado por s2 al objeto apuntado por s1. La función devuelve un puntero a s1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
que copia n bytes del objeto apuntado por s2 al objeto apuntado por s1. La función devuelve un puntero a s1:
 
struct str_a
{
	char	a;
	char	b;
	char	c[16];
};
 
char	v_string[256];
 
int main (void)
{
	struct str_a v_01;
	int	i;
	void *ptr;
 
	v_01.a = '9';
	v_01.b = '1';
	strcpy(v_01.c, "TEST");
	ptr = (char *)&v_01;
 
	memcpy(v_string, ptr, sizeof(v_01));
	printf("Resultado: %s\n", v_string);
	return 0;
}

Para comprender bien estas dos últimas, debes conocer bien el manejo de punteros. Si tienes dudas, ya sabes donde estamos.

Saludos,
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por jaldonfer (31 intervenciones) el 02/12/2014 15:06:06
Hola:

Muchas Gracias.

Me ha sido muy util.

Me ha surgido otra duda.

Cuanto mide una estructura ?



Si defino esta estructura:

struct Str_01 {

int a;
char c[10];
};

//Declaracion de variables auxiliares
struct Str_01 Lcl_V01 = {0};
printf("sizeof Lcl_V01: [%d]\n", sizeof(Lcl_V01));

...me traza:
sizeof Lcl_V01: [16]

si el char c de la estructura lo defino de [12] me traza:
sizeof Lcl_V01: [16]

pero si lo defino de [13] me traza
sizeof Lcl_V01: [20]


¿ No debería ser una suma de los que midan en bytes todos sus datos ?

Muchas Gracias y Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por Capitan Kirk capitan.kirk08@gmail.com (1 intervención) el 02/12/2014 15:22:29
En principio sí, lo que ocurre es que, por cuestiones de direccionamiento de memoria, los objetos en la memoria siempre estarán en direcciones que comiencen por un múltiplo de 4 (en el caso de máquinas de 32 bits). Así, en la primera estructura, tienes:

Un entero (4 bytes)
Un array de 10 caracteres (10 bytes)
10+4 = 14

pero el siguiente elemento tendría que ubicarlo 16 bytes más allá del comienzo de la estructura, por tanto la estructura te va a ocupar 16 bytes en lugar de los 14 teóricos.

En el segundo caso tienes:

Un entero (4 bytes)
Un array de 12 caracteres (12 bytes)
12+4 = 16

en este caso sí te coincide la ocupación teórica con la real.

En el último caso tienes:

Un entero (4 bytes)
Un array de 13 caracteres (13 bytes)
13+4 = 17

el siguiente elemento tendría que ubicarlo 20 bytes más allá del comienzo de la estructura, por tanto la estructura te va a ocupar 20 bytes en lugar de los 17 teóricos.

En resumen: En casos como este debes ser muy cauto, y probar para ver cómo hace la máquina las cosas. Ten en cuenta que estás manejando directamente la memoria, y eso te puede dar problemas si no tienes cuidado.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por jaldonfer (31 intervenciones) el 02/12/2014 19:21:42
Hola:

Gracias por la respuesta. Lo tendré en cuenta.


Una ultima cosa....


Como puedo hacer para copiar partes de una estructura en un array de char ?

Es decir, tengo la siguiente estructura:


struct str_a {

char c_01;
char c_02;
char c_03[16];
char c_04[10];
char c_05[16];
char c_06[6];
char c_07[16];
char c_08[12];
int i_01;
}

struct str_a xxx = {0};

y la siguiente variable

char V_CHAR[265] = "";

y quiero copiar xxx .c_01, xxx c_04, xxx c_06, xxx c07 e xxx i_01 a V_CHAR, concatenendo un total de 21 bytes.


Lo he intentado con strcat y strncat, pero no estoy seguro de que sea la forma más apropiada ya que son funciones dedicadas a strings y si pod lo que sea se encunetra un valor 0 lo interpreta como caracter nulo y deja de copiar.

Tambien he intentado con memcpy, pero no se como se hace en este caso para copiar en la variable de destino desde un byte determinado en adelante ( desde el ultimo byte que se copió )


Espero haberme explicado

Muchas Gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por Tom (481 intervenciones) el 02/12/2014 19:21:56
Bueno, hay que matizar. Ni todos los "objetos" usan un "alineamiento" específico (para los char puede ser 1, por ejemplo) ni siempre será a un múltiplo de 4 (para los long o double puede ser 8, por ejemplo).
Depende del compilador, de las opciones de compilación, del tipo de CPU, y de los "pragma" que hayas podido usar en tu código fuente.

Por ejemplo, el gcc admite este pragma:

1
2
3
4
5
6
struct {
  char fill1;
  long  fill2;
  short fill3;
  char fill4
} __attribute__ ((packed));

https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Type-Attributes.html
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por jaldonfer (31 intervenciones) el 02/12/2014 19:38:26
Hola:

No entiendo....

Para que sirve exactamente lo de __attribute__ ((packed)); ?

Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por Tom (481 intervenciones) el 03/12/2014 09:05:25
¿ Por qué no lees el enlace que pegué ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Como copiar memoria

Publicado por Capitan Kirk capitan.kirk09@gmail.com (94 intervenciones) el 02/12/2014 19:50:56
Así es, el alineamiento depende del compilador, opciones de compilación, pragmas, etc. Simplemente, no he querido complicar demasiado mi respuesta anterior.

Efectivamente, las funciones strcat y strncat dejan de copiar cuando encuentran un valor 0. Lo que ocurre es que, en C, las cadenas de caracteres (que, en realidad no son más que arrays de caracteres) tienen el carácter 0 (NULL) como terminador (indicador de fin de cadena). Por tanto, las funciones relacionadas con cadenas de caracteres consideran que cuando se alcanza el carácter 0 finaliza la cadena. Cuando reserves espacio para una cadena de caracteres debes tener en cuenta que también hay que reservar espacio para ese carácter nulo.

Para eso que quieres hacer, tendrás que utilizar punteros. En C, los punteros son una herramienta muy poderosa, y hay que dominar su manejo si quieres hacer algo que vaya más allá del "Hola mundo". Pero, si no los manejas bien, pueden conducirte al desastre.

Puedes hacerte una idea de cómo se haría con punteros si te fijas en el segundo ejemplo de mi primera respuesta. No se hace exactamente así, pero puede darte una idea de por dónde van los tiros.

Y, lo dicho, cuando aprendas a manejar punteros, direcciones y arrays, y cómo se interrelacionan, podrás hacer juegos malabares con C.

Saludos,
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar