Autor
|
Tema: Punteros y memoria dinamica (Leído 2,561 veces)
|
bemone
Desconectado
Mensajes: 74
|
Buenas tardes gente, Estoy aprendiendo C y me estoy rompiendo el marote contra la pared bien fuerte. Tengo una estructura Persona. La cual quiero manipularla dinamicamente a traves de la estructura Array (TDA) y me surgio un problema que desconozco a que se puede deber. Si cargo el array desde el main() todo funciona perfecto. Cuando lo quiero cargar a traves de un metodo, se rompe todo. He aqui el codigo: #include <stdio.h> #include <stdlib.h> #include <time.h> typedef struct persona{ char *nombre; int edad; int sexo; }Persona; typedef struct { int size; Persona vecPersona[]; }Array; Array* getArrayInstance(){ Array *vec; vec = (Array *) malloc (sizeof(Persona )); vec->size = 0; return vec; } void push_back(Array ** vec, Persona tipito){ (*vec)->vecPersona[(*vec)->size] = tipito; (*vec)->size++; int newSize = (*vec)->size*2-(*vec)->size+1; Array *tmp = realloc((*vec ), newSize *sizeof(Persona )); if(tmp) *vec = tmp; else (*vec)->size--; } void mostrarPersonas(Array *vec){ int i; for(i=0; i<vec->size; i++){ printf("(%d) Nombre: %s - Edad: %d - Sexo: ", i , vec ->vecPersona [i ]. nombre, vec ->vecPersona [i ]. edad); if(vec->vecPersona[i].sexo == 0) else } } void cargarPersonas(Array **vec){ int i, edad, random; int cantPersonas = rand()%30+1; Persona aux; char **hombres = {"Ramiro","Pedro","Federico","Jose","Antonio","Pablo","Raul","Gustavo","Gonzalo","Airton"}; char **mujeres = {"Mariana","Jennifer","Luz","Roxana","Ana","Sol","Micaela","Romina","Melina","Camila"}; for(i=0; i<cantPersonas; i++){ aux.edad = edad; if( (random = rand()%10) %2 == 0){ // hombres aux.nombre = hombres[random]; aux.sexo = 0; } else{ aux.nombre = mujeres[random]; aux.sexo = 1; } push_back(vec, aux); } } int main() { Array *vecPersonas = getArrayInstance(); Persona aux; aux.nombre="Cecilia"; aux.edad=27; aux.sexo=0; push_back(&vecPersonas, aux); // Esto anda push_back(&vecPersonas, aux); // Esto anda push_back(&vecPersonas, aux); // Esto anda push_back(&vecPersonas, aux); // Esto anda push_back(&vecPersonas, aux); // Esto anda push_back(&vecPersonas, aux); // Esto anda //cargarPersonas(&vecPersonas); // Esto no //printf("%d", vecPersonas->size); mostrarPersonas(vecPersonas); return 0; }
|
|
« Última modificación: 28 Agosto 2015, 19:25 pm por bemone »
|
En línea
|
Odio los tipos de variable de Windows.
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
Array* getArrayInstance(){ Array *vec; vec = (Array *) malloc (sizeof(Persona )); vec->size = 0; return vec; }
(Array*) malloc(sizeof(Persona)); Si vas a crear un Array, entonces tendrás que poner sizeof(Array), puesto que Array tiene un tamaño de sizeof(Persona*) + sizeof(int) = 8 bytes, mientras que Persona tiene un tamaño de 12 bytes.
|
|
|
En línea
|
|
|
|
bemone
Desconectado
Mensajes: 74
|
Array* getArrayInstance(){ Array *vec; vec = (Array *) malloc (sizeof(Persona )); vec->size = 0; return vec; }
(Array*) malloc(sizeof(Persona)); Si vas a crear un Array, entonces tendrás que poner sizeof(Array), puesto que Array tiene un tamaño de sizeof(Persona*) + sizeof(int) = 8 bytes, mientras que Persona tiene un tamaño de 12 bytes. Perdon, creo que me exprese mal. Quiero un Array dinamico dentro de una estructura. Lo que me decis vos es para crear un array de Array.
|
|
|
En línea
|
Odio los tipos de variable de Windows.
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
No, es correcto. Pon malloc(sizeof(Array)), puesto que estás reservando memoria del tamaño de Array. Otra cosa importante: en vez de: Persona vecPersona[];
pon: Persona *vecPersona;
Puesto que es un puntero. Además, tienes otros errores como, en push_back: int newSize = (*vec)->size*2-(*vec)->size+1;
No sé qué pretendes sacar con esa ecuación. Al principio, siendo size=1, haces un realloc((*vec)->vecPersona, 0). Y ya luego, valores altos. Eso debería quedar: int newSize = (*vec)->size+1;
En fin, he reconstruido esa función: void push_back(Array ** vec, Persona tipito){ int newSize = (*vec)->size+1; Persona *tmp = realloc((*vec )->vecPersona , newSize *sizeof(Persona )); if(tmp){ (*vec)->vecPersona = tmp; (*vec)->vecPersona[(*vec)->size] = tipito; (*vec)->size++; } }
Además, inicialicé el contenido de vecPersona en getArrayInstance: Array* getArrayInstance(){ Array *vec; vec = (Array *) malloc (sizeof(Array )); vec->vecPersona = 0; vec->size = 0; return vec; }
Y otro tema muy importante: char *hombres[] = {"Carlos", "Pablo"};
No puedes poner un doble puntero para ser inicializado de ese modo. Además, en push_back te recomiendo poner: (*vec )->vecPersona [(*vec )->size ]. nombre = (char*) malloc((strlen(tipito. nombre)+1)*sizeof(char)); strcpy((*vec )->vecPersona [(*vec )->size ]. nombre, tipito. nombre);
Copiar las cadenas, no copiar los punteros, puesto que si se libera la memoria de uno de ellos, todos los demás perderán lso datos, y podrán tirar errores. Claro que si vas a hacer un método "pop", tendrás que recordar liberarlos. Bueno, este es el código completo, por si quieres ver qué se cambió más claramente: Para strlen y strcpy, la librería <string.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> typedef struct persona{ char *nombre; int edad; int sexo; }Persona; typedef struct { int size; Persona *vecPersona; }Array; Array* getArrayInstance(){ Array *vec; vec = (Array *) malloc (sizeof(Array )); vec->vecPersona = 0; vec->size = 0; return vec; } void push_back(Array ** vec, Persona tipito){ int newSize = (*vec)->size+1; Persona *tmp = realloc((*vec )->vecPersona , newSize *sizeof(Persona )); if(tmp){ (*vec)->vecPersona = tmp; (*vec)->vecPersona[(*vec)->size] = tipito; (*vec )->vecPersona [(*vec )->size ]. nombre = (char*) malloc((strlen(tipito. nombre)+1)*sizeof(char)); strcpy((*vec )->vecPersona [(*vec )->size ]. nombre, tipito. nombre); (*vec)->size++; } } void mostrarPersonas(Array *vec){ int i; for(i=0; i<vec->size; i++){ printf("(%d) Nombre: %s - Edad: %d - Sexo: ", i , vec ->vecPersona [i ]. nombre, vec ->vecPersona [i ]. edad); if(vec->vecPersona[i].sexo == 0) else } } void cargarPersonas(Array **vec){ int i, edad, random; int cantPersonas = rand()%30+1; Persona aux; char *hombres[] = {"Ramiro","Pedro","Federico","Jose","Antonio","Pablo","Raul","Gustavo","Gonzalo","Airton"}; char *mujeres[] = {"Mariana","Jennifer","Luz","Roxana","Ana","Sol","Micaela","Romina","Melina","Camila"}; for(i=0; i<cantPersonas; i++){ aux.edad = edad; if( (random = rand()%10) %2 == 0){ // hombres aux.nombre = hombres[random]; aux.sexo = 0; } else{ aux.nombre = mujeres[random]; aux.sexo = 1; } push_back(vec, aux); } } int main() { Array *vecPersonas = getArrayInstance(); cargarPersonas(&vecPersonas); // Esto no printf("%d", vecPersonas ->size ); mostrarPersonas(vecPersonas); return 0; }
|
|
|
En línea
|
|
|
|
geeke
Desconectado
Mensajes: 93
|
Otra aproximación con la correspondiente liberación de memoria del array de estructuras y algunas que otras mejoras #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> typedef struct Persona { char *nombre; int edad; int sexo; } Persona; typedef struct { Persona *array; size_t used; size_t size; } Array; void initArray(Array *a, size_t initialSize) { a ->array = (Persona *)calloc(initialSize , sizeof(Persona )); a->used = 0; a->size = initialSize; } void push_back(Array *a, Persona element) { if (a->used == a->size) { a->size *= 2; a ->array = (Persona *)realloc(a ->array , a ->size * sizeof(Persona )); memset(&a ->array [a ->used ],0,sizeof(Persona ) * (a ->size - a ->used )); } a ->array [a ->used ]. nombre = (char*)malloc(strlen(element. nombre) + 1); strcpy(a ->array [a ->used ]. nombre, element. nombre); a->array[a->used].edad = element.edad; a->array[a->used].sexo = element.sexo; a->used++; } void freeArray(Array *a) { int i; for (i = 0; i < a->used; i++) { free(a ->array [i ]. nombre); a->array[i].nombre = NULL; } a->array = NULL; a->used = 0; a->size = 0; } void cargarPersonas(Array * arr) { int i, edad, random; int TAM = rand() % 30 + 1; Persona temp; char *hombres[] = {"Ramiro","Pedro","Federico","Jose","Antonio","Pablo","Raul","Gustavo","Gonzalo","Airton"}; char *mujeres[] = {"Mariana","Jennifer","Luz","Roxana","Ana","Sol","Micaela","Romina","Melina","Camila"}; for ( i = 0; i < TAM; i++) { temp.edad = edad; if( (random = rand() % 10) % 2 == 0) { temp.nombre = hombres[random]; temp.sexo = 0; } else { temp.nombre = mujeres[random]; temp.sexo = 1; } push_back(arr, temp); } } void mostrarPersonas(Array *arr) { int i; for ( i = 0; i < arr->used; i++) { printf("(%d) Nombre: %s - Edad: %d - Sexo: ", i , arr ->array [i ]. nombre, arr ->array [i ]. edad); if ( arr->array[i].sexo == 0) else } } int main(void) { Array a; initArray(&a, 5); cargarPersonas(&a); mostrarPersonas(&a); freeArray(&a); return 0; }
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
quien me puede ayudar a pasar este codigo con punteros y memoria dinamica
Programación C/C++
|
attackers
|
3
|
2,755
|
23 Noviembre 2011, 13:04 pm
por attackers
|
|
|
Array de estructura (struct) typedef y punteros[C].
« 1 2 »
Programación C/C++
|
DanielPy
|
17
|
12,273
|
26 Mayo 2015, 01:00 am
por normaaaaaaaa
|
|
|
Consutla sobre un problema con punteros y memoria dinamica.
Programación C/C++
|
Arturo400
|
1
|
1,753
|
22 Septiembre 2016, 22:15 pm
por AlbertoBSD
|
|
|
Consulta sobre punteros y memoria dinámica
Programación C/C++
|
ing_maipu
|
5
|
4,095
|
18 Octubre 2017, 19:21 pm
por ing_maipu
|
|
|
Retornar punteros char? ¿Si o si memoria dinamica?
« 1 2 »
Programación C/C++
|
Xargam
|
11
|
5,684
|
27 Junio 2018, 00:26 am
por ThunderCls
|
|