Quiero copiar una estructura idéntica en otra y luego usarla como comparación con la primera. ¡La cosa es que mi compilador me da una advertencia cuando estoy haciendo esto! ¿Debo hacerlo de otra manera o estoy haciendo esto mal?
struct RTCclk RTCclk;
struct RTCclk RTCclkBuffert;
void FunctionDO(void)
{
... // Some Code
/* Copy first struct values into the second one */
memcpy(&RTCclk, &RTCclkBuffert, sizeof RTCclk);
}
¿Qué advertencia da el compilador?
– Nick Shaw
3 de febrero de 2012 a las 10:39
PD: ¿no debería ser el tamaño de la llamada? sizeof(RTCclk)no sizeof TRCclk?
– Nick Shaw
3 de febrero de 2012 a las 10:40
solo una advertencia [2054] Conversión de puntero sospechosa, ¿debería usar memset o memmove en su lugar?
– cristiano
3 de febrero de 2012 a las 10:43
@NickShaw: los paréntesis son redundantes, como en i = (2)+(4);. no me gustan; algunas otras personas lo hacen.
– pmg
3 de febrero de 2012 a las 10:44
La única referencia que puedo encontrar a “Advertencia [2054] conversión de puntero sospechosa” se relaciona con los compiladores de Microchip para PIC. Se puede acceder a sus mapas de memoria de diferentes maneras y pueden verse afectados por cosas como la banca, por lo que debe verificar dos veces cuál es la firma de memcpy() y dónde han estado sus variables colocado por el enlazador Quizás usar la asignación de estructura como se ha respondido es la opción más segura.
– hombre de hojalata
3 de febrero de 2012 a las 10:56
Para estructuras simples puedes usar memcpy como lo haces tú, o simplemente asigna de uno a otro:
RTCclk = RTCclkBuffert;
El compilador creará un código para copiar la estructura por usted.
Una nota importante sobre la copia: es una copia superficial, al igual que con memcpy. Eso significa que si tiene, por ejemplo, una estructura que contiene punteros, solo se copiarán los punteros reales y no a qué apuntan, por lo que después de la copia tendrá dos punteros apuntando a la misma memoria.
¿Funciona incluso si tengo arreglos dentro de la estructura? como: ejemplo de estructura{ int misCosas[10000]; nombre del personaje[100]; identificación interna; };
– M4rk
07/01/2014 a las 16:35
¿Cómo hago una copia profunda entonces?
– Usuario
27 de marzo de 2015 a las 6:17
@User Si la estructura no contiene punteros, y las estructuras contenidas no contienen punteros, y así sucesivamente, entonces se soluciona. Si hay punteros en cualquier lugar, debe asignar nueva memoria y copiar usando, por ejemplo memcpy.
– Un tipo programador
27 de marzo de 2015 a las 6:19
Sí, es una lista enlazada. Entonces, ¿solo memcpy el primer elemento en la lista vinculada?
– Usuario
27 de marzo de 2015 a las 6:21
@User Si desea copiar una lista, la forma más fácil es crear una lista completamente desde cero. Recorra la lista existente y obtenga sus datos, luego agréguelos a la nueva lista.
– Un tipo programador
27 de marzo de 2015 a las 6:24
graham borland
Su código es correcto. También puede asignar uno directamente al otro (ver la respuesta de Joachim Pileborg).
Cuando luego venga a comparar las dos estructuras, debe tener cuidado de comparar las estructuras a lo largo, un miembro a la vez, en lugar de usar memcmp; ver ¿Cómo se comparan las estructuras para la igualdad en C?
Entonces debería hacer algo como esto: dowhile ( RTCclk.segundo != RTCclkBuffert.segundo || RTCclk.minuto != RTCclkBuffert.minuto || RTCclk.hora != RTCclkBuffert.hora || RTCclk.mday != RTCclkBuffert.mday) ;
– cristiano
3 de febrero de 2012 a las 12:09
Si. Aunque sería mejor envolver la comparación en una función.
–Graham Borland
3 de febrero de 2012 a las 12:12
copie la estructura en c, solo necesita asignar los valores de la siguiente manera:
struct point{int x,y;};
typedef struct point point_t;
typedef struct
{
struct point ne,se,sw,nw;
}rect_t;
rect_t temp;
int main()
{
//rotate
RotateRect(&temp);
return 0;
}
void RotateRect(rect_t *givenRect)
{
point_t temp_point;
/*Copy struct data from struct to struct within a struct*/
temp_point = givenRect->sw;
givenRect->sw = givenRect->se;
givenRect->se = givenRect->ne;
givenRect->ne = givenRect->nw;
givenRect->nw = temp_point;
}
Tu memcpy el código es correcto.
Supongo que le falta una inclusión de string.h. Entonces el compilador asume un prototipo incorrecto de memcpy y por lo tanto la advertencia.
De todos modos, solo debe asignar las estructuras en aras de la simplicidad (como señaló Joachim Pileborg).
memcpy para estructuras dice “No sé si el lenguaje que estoy usando admite la asignación de estructuras”. La única razón para usar memcpy entre dos estructuras del mismo tipo es que, por alguna razón, debe asegurarse de que el relleno de la estructura se conserve exactamente.
– Kaz
13 de febrero de 2016 a las 19:42
Dan
memcpy espera que los dos primeros argumentos sean nulos*.
PS aunque no es necesario, la convención dicta los corchetes para el tamaño del operador. Puede salirse con la suya con muchas cosas en C que hacen que el código sea imposible de mantener, por lo que seguir las convenciones es la marca de un buen programador de C (empleable).
memcpy para estructuras dice “No sé si el lenguaje que estoy usando admite la asignación de estructuras”. La única razón para usar memcpy entre dos estructuras del mismo tipo es que, por alguna razón, debe asegurarse de que el relleno de la estructura se conserve exactamente.
– Kaz
13 de febrero de 2016 a las 19:42
Alfa
Creo que debería lanzar los punteros a (void *) para deshacerse de las advertencias.
También puede usar sizeof sin corchetes, puede usar esto con variables, pero si RTCclk se definió como una matriz, sizeof devolverá el tamaño completo de la matriz. Si usa use sizeof con tipo, debe usar con corchetes.
sizeof(struct RTCclk)
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información
¿Qué advertencia da el compilador?
– Nick Shaw
3 de febrero de 2012 a las 10:39
PD: ¿no debería ser el tamaño de la llamada?
sizeof(RTCclk)
nosizeof TRCclk
?– Nick Shaw
3 de febrero de 2012 a las 10:40
solo una advertencia [2054] Conversión de puntero sospechosa, ¿debería usar memset o memmove en su lugar?
– cristiano
3 de febrero de 2012 a las 10:43
@NickShaw: los paréntesis son redundantes, como en
i = (2)+(4);
. no me gustan; algunas otras personas lo hacen.– pmg
3 de febrero de 2012 a las 10:44
La única referencia que puedo encontrar a “Advertencia [2054] conversión de puntero sospechosa” se relaciona con los compiladores de Microchip para PIC. Se puede acceder a sus mapas de memoria de diferentes maneras y pueden verse afectados por cosas como la banca, por lo que debe verificar dos veces cuál es la firma de memcpy() y dónde han estado sus variables colocado por el enlazador Quizás usar la asignación de estructura como se ha respondido es la opción más segura.
– hombre de hojalata
3 de febrero de 2012 a las 10:56