Autor
|
Tema: Dimensionar un vector dentro de un struct (Leído 7,519 veces)
|
ShadowA7X
Desconectado
Mensajes: 19
|
Que tal chicos y chicas,disculpen la pregunta pero me puse ante los diversos casos en el manejo de structs y éste (que creo que es básico) no lo puedo hacer. #include <stdio.h> typedef struct humano{ int *trabajos; }persona; int main(){ int cantidad_personas=8; int cantidad_trabajos=4; persona *primera; primera =(persona *)malloc(sizeof(persona )*cantidad_personas ); /* Hasta este punto por lo que entiendo hice un arreglo dinamico en donde ubicamos a la persona en un espacio del arreglo*/ //Ahora bien cada persona tendrá más de un trabajo por lo cual el puntero //trabajo (*trabajos) debemos convertirlo en un vector. return 0; }
Mi pregunta es ¿cómo hago eso? el *primera que es de tipo persona lo transformamos en un vector dinámico, pero una vez hecho eso ¿Cómo transformo el puntero que ésta dentro de *primera en otro vector? De antemano muchas gracias.
|
|
« Última modificación: 8 Noviembre 2014, 19:41 pm por ShadowA7X »
|
En línea
|
|
|
|
kutcher
Desconectado
Mensajes: 53
|
¿Cómo transformo el puntero que ésta dentro de *primera en otro vector?
Simple: primera -> trabajos = malloc(... );
Saludos
|
|
|
En línea
|
|
|
|
ShadowA7X
Desconectado
Mensajes: 19
|
Simple: primera -> trabajos = malloc(... );
Saludos Por ahí como que funciona pero con errores. Por ejemplo hice esta cosa que tiene que imprimir por pantalla del 1 al 32, pero sólo imprime los últimos 4 números(29,30,31,32) ocho veces. #include <stdio.h> typedef struct humano{ int *trabajos; }persona; int main(){ int i,j,cont=1; int cantidad_personas=8; int cantidad_trabajos=4; persona *primera; primera =(persona *)malloc(sizeof(persona )*cantidad_personas ); primera ->trabajos =(int *)malloc(sizeof(int)*cantidad_trabajos ); for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ primera->trabajos[j]=cont; cont++; } } for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ printf("%d ",primera ->trabajos [j ]); } } return 0; }
Y si le pongo un contador a primera (es decir primera [i] ->
no me compila ) qué pasa?
|
|
« Última modificación: 8 Noviembre 2014, 20:18 pm por ShadowA7X »
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
No sería primera[ i ]->, porque ya no sería puntero. Sería primera[ i ].trabajos (etc)
|
|
« Última modificación: 8 Noviembre 2014, 21:32 pm por ivancea96 »
|
En línea
|
|
|
|
plataplomo2948
Desconectado
Mensajes: 12
|
1. Estas usando un puntero doble... por que? 2. El tomano del int siempre va a ser 4 bytes. Por cada persona, hay que allocar otro struct. Si no quiere hacer eso, hay que poner mas variables dentro de su struct. Trata eso, pra mi funciono typedef struct Humano { int Trabajos; } HUMANO, *PHUMANO; int main () { PHUMANO Primera = (PHUMANO)malloc(sizeof(HUMANO));
Primera->Trabajos = (int)malloc(sizeof(int)); // nunca debe hacer eso por que es allocacion dinamica y eso es un valor estatico pero // solo es pra mostrar como funciona Primera->Trabajos = 248;
printf("Primera->Trabajos = %i\n", Primera->Trabajos); free((int*)Primera->Trabajos); free(Primera); return 0; }
Acabo de ver eso, y en ese caso no es necesario usar la alocacion dinamica porque en linea 10 "cont" es un valor estatico. Es decir que ya esta en el stack y la memora ya viene allocada del imagen. modificacion - disculpe - en linea 11 es la declaracion estatica y en linea 23 pongas un valor dinamica a un valor estatica.
Ok, veo porque usa un puntero doble. Quiere hacer un int array dentro de un struct. Debe hacer asi: typedef struct Humano { int* Trabajos; } HUMANO, *PHUMANO; int main () { // eso coresponde al tomano de su array int NumeroDeElementos = 30; PHUMANO Primera = (PHUMANO)malloc(sizeof(HUMANO));
Primera->Trabajos = (int*)malloc(sizeof(int) * NumeroDeElementos); // nunca debe hacer eso por que es allocacion dinamica y eso es un valor estatico pero // solo es pra mostrar como funciona Primera->Trabajos[15] = 248;
printf("Primera->Trabajos = %i\n", Primera->Trabajos[15]); free((int*)Primera->Trabajos); free(Primera); return 0; }
modificaion - se me olvido poner un *
|
|
« Última modificación: 8 Noviembre 2014, 22:03 pm por Eternal Idol »
|
En línea
|
|
|
|
ShadowA7X
Desconectado
Mensajes: 19
|
Ok, veo porque usa un puntero doble. Quiere hacer un int array dentro de un struct. Debe hacer asi: typedef struct Humano { int* Trabajos; } HUMANO, *PHUMANO; int main () { // eso coresponde al tomano de su array int NumeroDeElementos = 30; PHUMANO Primera = (PHUMANO)malloc(sizeof(HUMANO));
Primera->Trabajos = (int*)malloc(sizeof(int) * NumeroDeElementos); // nunca debe hacer eso por que es allocacion dinamica y eso es un valor estatico pero // solo es pra mostrar como funciona Primera->Trabajos[15] = 248;
printf("Primera->Trabajos = %i\n", Primera->Trabajos[15]); free((int*)Primera->Trabajos); free(Primera); return 0; }
modificaion - se me olvido poner un * Primero muchas gracias por darte el tiempo de sacarme esta duda hermano, en verdad te lo agradezco. 1-Porque el vector de tipo persona es dinámico y contiene otro vector dinámico en su interior. 2- Pero cada persona será representada por la casilla del vector, y esa casilla/persona tiene asignadas muchas tareas (que en este caso es 4 por ej), según el programa y los for que tengo, puedo moverme por las tareas pero no por las personas (pues no puedo agregar un contador "i" a la persona para irla recorriendo (la idea es no agregar variables al struct y usar lo que está). Este ejemplo de 32 es sumamente improvisado, es sólo para tener la idea, pero ud que cambiaría para que el programa pueda imprimir del 1 al 32 y que no imprima el 29,30,31 y 32 ocho veces? Así como ejemplo mi programa está así: #include <stdio.h> typedef struct humano{ int *trabajos; }persona; int main(){ int i,j,cont=1; int cantidad_personas=8; int cantidad_trabajos=4; persona *primera; primera =(persona *)malloc(sizeof(persona )*cantidad_personas ); primera ->trabajos =(int *)malloc(sizeof(int)*cantidad_trabajos ); for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ primera->trabajos[j]=cont; cont++; } } for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ printf("%d ",primera ->trabajos [j ]); } } return 0; }
Y en un mundo ideal, lo que yo quiero es que avance por las personas y los trabajos así (aclaro este no compila pero si compilara haría lo que yo quiero(bajo una logica algoritmica)): #include <stdio.h> typedef struct humano{ int *trabajos; }persona; int main(){ int i,j,cont=1; int cantidad_personas=8; int cantidad_trabajos=4; persona *primera; primera =(persona *)malloc(sizeof(persona )*cantidad_personas ); primera ->trabajos =(int *)malloc(sizeof(int)*cantidad_trabajos ); for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ primera[i]->trabajos[j]=cont; cont++; } } for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ printf("%d ",primera [i ]->trabajos [j ]); } } return 0; }
Ud cómo le haría/modificaría tomando en cuenta el mismo ejemplo que le muestro?
|
|
|
En línea
|
|
|
|
plataplomo2948
Desconectado
Mensajes: 12
|
Bueno, me parece que usted sabe de lo que habla aun que no entiendo exactamente cual es su objectivo final, pero eso es como hacer el codigo para que compila bien. Eso imprima hasta 32. La proxima vez, deberia poner su error de compilicaion y decir que quiere hacer "un array de int dentro de un array de struct" : ) suerte typedef struct Humano { int* Trabajos; } HUMANO, *PHUMANO; int main () { int CantidadDeTrabajos = 4; // int CantidadDePersonas = 8; // personas int Cont = 0; // declarar espacio por un array de struct PHUMANO Primera = (PHUMANO)malloc(sizeof(HUMANO) * CantidadDePersonas); // por cada persona, declara un array dentro el struct for (int i = 0; i < CantidadDePersonas; i++) Primera[i].Trabajos = (int*)malloc(sizeof(int) * CantidadDeTrabajos); for (int i = 0; i < CantidadDePersonas; i++) { for (int j = 0; j < CantidadDeTrabajos; j++) { Cont += 1; Primera[i].Trabajos[j] = Cont; } } for (int i = 0; i < CantidadDePersonas; i++) for (int j = 0; j < CantidadDeTrabajos; j++) printf("Trabajo#%i\n", Primera[i].Trabajos[j]); //Primera[0].Trabajos[0] = 248;
//printf("Primera->Trabajos = %i\n", Primera[0].Trabajos[0]); for (int i = 0; i < CantidadDePersonas; i++) free((int*)Primera[i].Trabajos); free(Primera); _getch (); return 0; }
Modificacion - Al respecto a 1 - no estamos trabajando con los vectores, estos son arrayes (son parecidos pero hay diferencias). Todavia si estariamos trabajando con vectores, la alocacion dinamica no seria necesario por ese codigo. Tambien, los vectores son de C++, asi que si quiere usar vectores - seria mejor usar new/delete en vez de malloc/free (eso no va a cambiar el comportamiento de su programa, solo para notar la diferencia entre C y C++ y por que no es mejor practica a mezclarlos). Generalmente, la alocacion dinamica es necesario solo cuando acepta algun tipo de input, sea de un archivo, stdin, socket, etc. Cuando hace un inicilizacion estatica (int i = 0), esa secion de memoria (los 4 bytes) SIEMPRE va a ser libre para manipular, si o si.
|
|
« Última modificación: 8 Noviembre 2014, 22:12 pm por plataplomo2948 »
|
En línea
|
|
|
|
ShadowA7X
Desconectado
Mensajes: 19
|
Bueno, me parece que usted sabe de lo que habla aun que no entiendo exactamente cual es su objectivo final, pero eso es como hacer el codigo para que compila bien. Eso imprima hasta 32. La proxima vez, deberia poner su error de compilicaion y decir que quiere hacer "un array de int dentro de un array de struct" : ) suerte typedef struct Humano { int* Trabajos; } HUMANO, *PHUMANO; int main () { int CantidadDeTrabajos = 4; // int CantidadDePersonas = 8; // personas int Cont = 0; // declarar espacio por un array de struct PHUMANO Primera = (PHUMANO)malloc(sizeof(HUMANO) * CantidadDePersonas); // por cada persona, declara un array dentro el struct for (int i = 0; i < CantidadDePersonas; i++) Primera[i].Trabajos = (int*)malloc(sizeof(int) * CantidadDeTrabajos); for (int i = 0; i < CantidadDePersonas; i++) { for (int j = 0; j < CantidadDeTrabajos; j++) { Cont += 1; Primera[i].Trabajos[j] = Cont; } } for (int i = 0; i < CantidadDePersonas; i++) for (int j = 0; j < CantidadDeTrabajos; j++) printf("Trabajo#%i\n", Primera[i].Trabajos[j]); //Primera[0].Trabajos[0] = 248;
//printf("Primera->Trabajos = %i\n", Primera[0].Trabajos[0]); for (int i = 0; i < CantidadDePersonas; i++) free((int*)Primera[i].Trabajos); free(Primera); _getch (); return 0; }
Modificacion - Al respecto a 1 - no estamos trabajando con los vectores, estos son arrayes (son parecidos pero hay diferencias). Todavia si estariamos trabajando con vectores, la alocacion dinamica no seria necesario por ese codigo. Tambien, los vectores son de C++, asi que si quiere usar vectores - seria mejor usar new/delete en vez de malloc/free (eso no va a cambiar el comportamiento de su programa, solo para notar la diferencia entre C y C++ y por que no es mejor practica a mezclarlos). Generalmente, la alocacion dinamica es necesario solo cuando acepta algun tipo de input, sea de un archivo, stdin, socket, etc. Cuando hace un inicilizacion estatica (int i = 0), esa secion de memoria (los 4 bytes) SIEMPRE va a ser libre para manipular, si o si. Hermano, no sabes como te lo hipermegacontramuchoAGRADESCO!!! gracias a lo que hiciste entendí perfectamente que era lo que me hacía falta. Adapte lo que tu hiciste a mi código y mi error fundamental salió a la luz!! lo dejo aquí para que quien tenga éste problema pueda solucinarlo: Mi código modificado según las apreciaciones de plataplomo2948 es éste: #include <stdio.h> typedef struct humano{ int *trabajos; }persona; int main(){ int i,j,cont=1; int cantidad_personas=8; int cantidad_trabajos=4; persona *primera; primera =(persona *)malloc(sizeof(persona )*cantidad_personas ); for (i=0; i < cantidad_personas; i++){ primera [i ]. trabajos=(int *)malloc(sizeof(int)*cantidad_trabajos ); } for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ primera[i].trabajos[j]=cont; cont++; } } for (i = 0; i < cantidad_personas; i++){ for (j = 0; j < cantidad_trabajos; j++){ printf("%d ",primera [i ]. trabajos[j ]); } } for (i = 0; i < cantidad_personas; i++){ free((int *) primera [i ]. trabajos); } return 0; }
Y él error fundamental que me permite ver toda la lógica de ésto era en ésta parte: for (i=0; i < cantidad_personas; i++){ primera [i ]. trabajos=(int *)malloc(sizeof(int)*cantidad_trabajos ); }
Al momento de dimensionar esa parte nunca se me ocurrió hacerlo dentro de un for, y bajo lo que ahora al fin entendí (corrijame plataplomo2948 si estoy equivocado) es obligación dimensionar cada espacio de primera en consideración a la cantidad de trabajos que haya. El código compila perfectamente y puedo dar por solucionada mi duda. Enserio plataplomo2948 infinitas gracias, ahora puedo hacer lo que realmente quiero . Por último si me permites molestarte, en la parte donde liberas memoria: for (int i = 0; i < CantidadDePersonas; i++) free((int*)Primera [i ]. Trabajos);
por qué se pone (int *) dentro del free y no sólo free(Primera [i ]. trabajos)?
Sólo esa pequeña duda me quedó, pero de antemano muchas gracias por todo bro, eres un crack!
|
|
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
No hay que poner (int*) dentro del free. free() recibe un parámetro void*. El haber puesto (int*) habrá sido una equivocación. (El tipo ya es int* de por sí)
|
|
|
En línea
|
|
|
|
plataplomo2948
Desconectado
Mensajes: 12
|
Es cuestion de preferencia y estilo (pra mi es mas facil leer) - no hace diferencia en el ASM que compila. Cosas asi no van a afectar el comprtamiento del programa y en ese caso solo es estitica.
tambem se me olvido hacer el checkeo de errores en el malloc(). tiene que hacer algo asi despues de cada llamada a malloc()
if Primera.Trabajos o Primera == NULL goto FINAL;
tambien, despues de liberarlos, tiene que poner el valor a cada variable a NULL. es buena practica para evitar la explotacion "use after free"
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Problema con struct dentro de libreria
« 1 2 »
Programación C/C++
|
dkmarley
|
10
|
9,711
|
23 Julio 2010, 16:51 pm
por dkmarley
|
|
|
[SOLUCIONADO]¿Como printear un valor de un struct dentro de otro struct?
Programación C/C++
|
Firos
|
0
|
5,186
|
24 Marzo 2011, 13:47 pm
por Firos
|
|
|
Un struct dentro de una matriz
Programación C/C++
|
freakx
|
2
|
6,380
|
23 Enero 2012, 02:16 am
por freakx
|
|
|
Ejercicio en C ayuda struct,tabla,vector datos
Programación C/C++
|
banguu
|
2
|
2,767
|
10 Noviembre 2015, 01:09 am
por banguu
|
|
|
Duda con respecto a struct dentro de struct
Programación C/C++
|
Naimaderis
|
1
|
3,485
|
2 Abril 2017, 00:10 am
por ivancea96
|
|