Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SARGE553413 en 21 Junio 2013, 01:45 am



Título: Duda con structs C/C++
Publicado por: SARGE553413 en 21 Junio 2013, 01:45 am
Hola a todos, expongo mi duda:

Tengo que usar la función gethostbyname(), que devuelve un struct hostent*. El problema es que este puntero está declarado como static, por tanto esta función devuelve SIEMPRE la misma dirección de memoria. Por tanto en sucesivas llamadas se van "pisando" datos. Quiero conseguir que ésto no pase.

La solución que se me ocurre es hacer otra función que "construya" otro hostent* no static, copiarle los valores y devolverlo.

Mi pregunta es si C/C++ tiene algún mecanismo para copiar estructuras (hacer "a=b" no me vale porque así se copian las direcciones de memoria).

Gracias.


Título: Re: Duda con structs C/C++
Publicado por: ralymontes en 21 Junio 2013, 05:19 am
Para copiar estructuras se tiene que hacer elemento a elemento. En el caso de los strings tienes que usar strcpy().

Saludos!


Título: Re: Duda con structs C/C++
Publicado por: amchacon en 21 Junio 2013, 13:08 pm
Para copiar estructuras se tiene que hacer elemento a elemento. En el caso de los strings tienes que usar strcpy().

Saludos!
Depende, en C++ se puede definir un operador = específico para la estructura:

Código
  1. struct Tonteria
  2. {
  3.    int Miau;
  4.    int* Cosa;
  5.  
  6.    Tonteria operator=(const Tonteria &t) // Operador =
  7.    {
  8.        Miau = t.Miau;
  9.        *Cosa = *t.Cosa;
  10.  
  11.        return *this; // Devuelvo una referencia a la misma clase, esto me sirve para concatenar varios =
  12.    }
  13. };

Y ya podrías usar el operador = sin problemas:

Código
  1. Tonteria1 = Tonteria2;


Título: Re: Duda con structs C/C++
Publicado por: xiruko en 21 Junio 2013, 14:42 pm
Pues a mi esto me funciona perfectamente...

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. struct prueba {
  5. int a;
  6. char b;
  7. char c[100];
  8. };
  9.  
  10. int main()
  11. {
  12. struct prueba p1, p2, *p3, p4;
  13.  
  14. // se inicializa p1
  15. p1.a = 10;
  16. p1.b = 'A';
  17. strcpy(p1.c, "ola k ase");
  18.  
  19. // se copia p1 a p2 y se imprime
  20. p2 = p1;
  21. printf("p2: %d %c %s\n", p2.a, p2.b, p2.c);
  22.  
  23. // p3 apunta a p1
  24. p3 = &p1;
  25.  
  26. // se copia *p3 a p4 y se imprime
  27. p4 = *p3;
  28. printf("p4: %d %c %s\n", p4.a, p4.b, p4.c);
  29. return 0;
  30. }

Así que sí, puedes copiar structs directamente. En el ejemplo que te he dado también lo tienes con punteros.

Saludos.


Título: Re: Duda con structs C/C++
Publicado por: amchacon en 21 Junio 2013, 14:48 pm
Pues a mi esto me funciona perfectamente...

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. struct prueba {
  5. int a;
  6. char b;
  7. char c[100];
  8. };
  9.  
  10. int main()
  11. {
  12. struct prueba p1, p2, *p3, p4;
  13.  
  14. // se inicializa p1
  15. p1.a = 10;
  16. p1.b = 'A';
  17. strcpy(p1.c, "ola k ase");
  18.  
  19. // se copia p1 a p2 y se imprime
  20. p2 = p1;
  21. printf("p2: %d %c %s\n", p2.a, p2.b, p2.c);
  22.  
  23. // p3 apunta a p1
  24. p3 = &p1;
  25.  
  26. // se copia *p3 a p4 y se imprime
  27. p4 = *p3;
  28. printf("p4: %d %c %s\n", p4.a, p4.b, p4.c);
  29. return 0;
  30. }

Así que sí, puedes copiar structs directamente. En el ejemplo que te he dado también lo tienes con punteros.

Saludos.
¿Seguro? Prueba esto:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. struct prueba {
  5. int a;
  6. char b;
  7. char c[100];
  8. };
  9.  
  10. int main()
  11. {
  12. struct prueba p1, p2, *p3, p4;
  13.  
  14. // se inicializa p1
  15. p1.a = 10;
  16. p1.b = 'A';
  17. strcpy(p1.c, "ola k ase");
  18.  
  19. // se copia p1 a p2 y se imprime
  20. p2 = p1;
  21. printf("p2: %d %c %s\n", p2.a, p2.b, p2.c);
  22.  
  23. // p3 apunta a p1
  24. p3 = &p1;
  25.  
  26. // se copia *p3 a p4 y se imprime
  27. p4 = *p3;
  28. printf("p4: %d %c %s\n", p4.a, p4.b, p4.c);
  29.  
  30.       // Ahora modifico c en p4)
  31.       p4.c[2] = 'z';
  32.  
  33.       // Compruebo p1... WTF QUE HA PASADO?
  34.  
  35.      printf("p1: %d %c %s\n", p1.a, p1.b, p1.c);
  36.  
  37. return 0;
  38. }

Estas usando la misma cadena en las 4 estructuras. Si modificas un dato en una la modificaras en todas ;)


Título: Re: Duda con structs C/C++
Publicado por: xiruko en 21 Junio 2013, 14:58 pm
Pues diciéndomelo tan seguro me esperaba que cambiara, pero si te soy sincero la salida de p1 es la del principio, sin la 'z' modificada xD

EDITO:

De hecho poder se puede:

http://stackoverflow.com/questions/9127246/copy-struct-to-struct-in-c (http://stackoverflow.com/questions/9127246/copy-struct-to-struct-in-c)

Lo único que no sé a qué se refiere con estructuras simples. Esta noche con más calma lo miro bien, que desde siempre he creído que se podían copiar y ahora resulta que no es tan trivial...

Saludos.


Título: Re: Duda con structs C/C++
Publicado por: amchacon en 21 Junio 2013, 15:13 pm
Pues diciéndomelo tan seguro me esperaba que cambiara, pero si te soy sincero la salida de p1 es la del principio, sin la 'z' modificada xD
Cierto, creo que ya he pillado el problema (un array no responda igual que un puntero al parecer).

Prueba ahora:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. struct prueba {
  5. int a;
  6. char b;
  7. char* c;
  8. };
  9.  
  10. int main()
  11. {
  12. struct prueba p1, p2, p3, p4;
  13.  
  14. // se inicializa p1
  15. p1.a = 10;
  16. p1.b = 'A';
  17. p1.c = new char[100];
  18. strcpy(p1.c, "ola k ase");
  19.  
  20. // se copia p1 a p2 y se imprime
  21. p2 = p1;
  22. printf("p2: %d %c %s\n", p2.a, p2.b, p2.c);
  23.  
  24. // p3 apunta a p1
  25. p3 = p1;
  26.  
  27. // se copia *p3 a p4 y se imprime
  28. p4 = p3;
  29. printf("p4: %d %c %s\n", p4.a, p4.b, p4.c);
  30.  
  31.    // Ahora modifico c en p4)
  32.   p4.c[2] = 'z';
  33.  
  34.    // Compruebo p1... WTF QUE HA PASADO?
  35.  
  36.      printf("p1: %d %c %s\n", p1.a, p1.b, p1.c);
  37.  
  38. return 0;
  39. }

De hecho poder se puede:

http://stackoverflow.com/questions/9127246/copy-struct-to-struct-in-c (http://stackoverflow.com/questions/9127246/copy-struct-to-struct-in-c)

Lo único que no sé a qué se refiere con estructuras simples. Esta noche con más calma lo miro bien, que desde siempre he creído que se podían copiar y ahora resulta que no es tan trivial...

Saludos.
Se puede hacer directamente si las estructuras no tienen punteros. Si los tiene te compilará pero te puedes encontrar problemas extraños en la ejecución (como ya he planteado antes).

Esta es una de las razones por las que se inventaron los operadores en C++.


Título: Re: Duda con structs C/C++
Publicado por: kmilinh0 en 21 Junio 2013, 15:40 pm
Debes reservar espacio en memoria para guardar las estructuras, lo mas directo es un array de estructuras hostent.

Posteriormente, puedes usar:

 memcpy( puntero1, puntero2, numeroBytes )

Esto es Ansi C, el clasico vamos. Esta funcion copia los bytes q quieras de una direccion de memoria a otra. Copiará de puntero2 a puntero1. Por tanto tu puntero1 es la posicion del array donde vayas a guardar la estructura hostent y puntero2 es el hostent*.

Código:
 memcpy( &array[i], hostent_puntero, sizeof(hostent) );
o algo asi jeje



Título: Re: Duda con structs C/C++
Publicado por: rir3760 en 21 Junio 2013, 17:33 pm
Pues diciéndomelo tan seguro me esperaba que cambiara, pero si te soy sincero la salida de p1 es la del principio, sin la 'z' modificada xD

EDITO:

De hecho poder se puede:

http://stackoverflow.com/questions/9127246/copy-struct-to-struct-in-c (http://stackoverflow.com/questions/9127246/copy-struct-to-struct-in-c)

Cierto, creo que ya he pillado el problema (un array no responda igual que un puntero al parecer).
No hay problema en utilizar el operador de asignación '=' para copiar estructuras pero se debe tener en cuenta el resultado de este:

A) Al copiarse un array se copia este como una unidad (el valor de todos sus elementos).

B) Al copiarse un puntero (para el caso cualquier objeto) se copia el valor almacenado.

En el ultimo caso y tratándose de punteros la dirección en memoria sera la misma y por ende un cambio en el objeto apuntado tendrá efecto en todas las estructuras (ya que todas apuntan a ese objeto).

Un saludo


Título: Re: Duda con structs C/C++
Publicado por: amchacon en 21 Junio 2013, 17:40 pm
Desconocía el punto A, creía que un array se tomaba como puntero ;)


Título: Re: Duda con structs C/C++
Publicado por: SARGE553413 en 21 Junio 2013, 18:09 pm
Gracias por las respuestas, sobre todo la del memcpy, muy interesante, no sabía que existiese esa función, gracias.

Pero supongamos que hago una funcion que devuelva un hostent*, en el cuerpo de esta función podría reservar memoria con malloc, y después usar el memcpy() sin necesidad de declarar y vector ¿cierto?

Otra cosa, si la estructura tiene dentro punteros, al usar memcpy(), ¿estos punteros apuntan correctamente no?, es decir, si tengo 2 vectores a y b, uno de tam. 20 y otro de tam. 40, en ese caso tras usar memcpy(), mis nuevos a y b tendrán también 20 y 40 de tamaño, ¿cierto?

Saludos y gracias de nuevo.


Título: Re: Duda con structs C/C++
Publicado por: zonahurbana en 21 Junio 2013, 18:32 pm
Depende, en C++ se puede definir un operador = específico para la estructura [...]

Tal vez no sea muy adecuado preguntar por acá, pero es una pregunta corta:
¿Cómo puedo encontrar más acerca de estos temas?
Es decir, ¿con qué nombre lo busco?

Con ello podría determinar las acciones de usar '+=' en clases que yo mismo vaya creando, ¿verdad?


Título: Re: Duda con structs C/C++
Publicado por: rir3760 en 21 Junio 2013, 18:45 pm
Pero supongamos que hago una funcion que devuelva un hostent*, en el cuerpo de esta función podría reservar memoria con malloc, y después usar el memcpy() sin necesidad de declarar y vector ¿cierto?
Tienes que explicarte de una forma mas clara, si puedes poner un ejemplo e indicar el lenguaje de programación que estas utilizando mejor.

Otra cosa, si la estructura tiene dentro punteros, al usar memcpy(), ¿estos punteros apuntan correctamente no?, es decir, si tengo 2 vectores a y b, uno de tam. 20 y otro de tam. 40, en ese caso tras usar memcpy(), mis nuevos a y b tendrán también 20 y 40 de tamaño, ¿cierto?
El tamaño de los campos depende de la declaración de la estructura, el uso de la función memcpy es tema aparte.

----

Depende, en C++ se puede definir un operador = específico para la estructura [...]

Tal vez no sea muy adecuado preguntar por acá, pero es una pregunta corta:
¿Cómo puedo encontrar más acerca de estos temas?
Es decir, ¿con qué nombre lo busco?
El tema es "Sobrecarga de operadores en C++", una pagina sobre ello es 22 Operadores V: Operadores sobrecargados (http://c.conclase.net/curso/?cap=022).

Un saludo


Título: Re: Duda con structs C/C++
Publicado por: pacoperico en 21 Junio 2013, 18:50 pm
Memcpy() copia literalmente un area de memoria en otro sitio de la memoria. Echale un ojo a su definicion para que lo tengas mas claro:

http://www.cplusplus.com/reference/cstring/memcpy/ (http://www.cplusplus.com/reference/cstring/memcpy/)