Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemas Con Vector.

Iniciado por nsL, 15 de Abril de 2005, 06:27:51 PM

« anterior - próximo »

nsL

 Jelow!

Os pongo un poco en antecedentes (brevemente):
Tenia y tengo una clase sprite que puede almacenar varios frames, para animaciones y tal, pero antes para almacenarlos usaba listas enlazadas, hasta q empece a tener problemas de memoria (al añadir cosa de 9 frames (surfaces) me petaba el asunto) asi q decidir cambiar a arrays dinamicos.
Tenia en mente hacer los arrays con calloc pero era un poco pestilente, asi q vi el template vector, que parece q suplia mis necesidades bien.

Esta misma tarde rehago todo el codigo para su uso con vector. Aqui os pego lo relevante al problema que tengo:


struct listaFram
{
 SDL_Surface *frame;
 bool *frmask;
};

vector<listaFram> frameList;

Esto es el "nodo" que usaba antes para las listas enlazadas y ahora para los elementos del array q me cree vector. Como veis creo un vector con 0 elementos.


void CSprite::addframe(char *Path)
{
listaFram *Aux = (listaFram *)malloc(sizeof(listaFram));
frameList.push_back(*Aux);
frameList[++total].frame = IMG_Load(Path);
}


Dejando al margen si compruebo si carga bien o mal el archivo, esta parte funciona bien. Pero solo para 1 frame, ahi esta mi problema. Si intento hacer otro addframe sobre el mismo sprite me salta el parachute famoso del SDL. Es la primera vez q uso vector y en mi libro de C++ tampoco se estira mucho el tio pa explicarlo, asi q puede ser q me olvide algo.

si sabeis q es os agradezco inmensamente la ayuda.

Saludos!  B)

PD: ya que estamos y para no abrir otro post.
Es muy descabellado gastar 13000 bytes por frame en una mascara? solo serian 13 kb por un frame de un boton. Para que os hagais una idea es una variable bool por pixel. 13000 variables bool suena mucho y a mi me parece exagerao quizas, pero frente a la ram tan grande, 13 kbs es insignificante.
Lo digo porq al añadir mascaras a los frames, si añado 2 mascaras o asi ya me peta el programa, supongo q sera porq no tiene memoria. Q pensais?
Yo no muero hasta la muerte -

samsaga2

 Una pista... el tipo del vector y de la variable que quieres agregar son distintos. Hasta aqui puedo leer.

Sacrifai

Cita de: "samsaga2"Una pista... el tipo del vector y de la variable que quieres agregar son distintos. Hasta aqui puedo leer.
Yo no veo eso  :huh: . Por cierto, me gustaría saber que tipo de error es ese "parachute" XDD y así poder ayudarte.


PD: Yo no reservaría memoria por cada frame que cargas. Haz que cada XX frames te reseve memoria para esos XX frames. El vector lo que hace es multiplicar por dos cuando se llega a su límite(por lo menos antes, no se si ahora harán eso) lo cual creo que es un desperdicio de memoria.

Warchief

 
void CSprite::addframe(char *Path)
{
listaFram *Aux = (listaFram *)malloc(sizeof(listaFram));
frameList.push_back(*Aux);
frameList[++total].frame = IMG_Load(Path);
}


"total" empieza en -1?

nsL

 
Citar
Fatal signal: Segmentation Fault (SDL Parachute Deployed)

Ese es el error, suele darme cuando referencias a una superficie pero q realmente no existe, ya sea porq no se pudo cargar u otro motivo. Aunq si te digo la verdad es el unico error q me da SDL, siempre el parachute :P

Citar
"total" empieza en -1?

Empieza en 0, y asigna a partir del 1. Es decir, frame 1, 2 ,3. Por eso primero incremento, pa posicionarlo en 1 para el primer frame y segun añada q lo meta en el siguiente hueco.

No entendi bien eso de que multiplica por 2, si puedes explica un poco mas plz ;)

Gracias a todos por la ayuda, a ver si consigo solventar esto.

Saludos!  B)  
Yo no muero hasta la muerte -

Sacrifai

 
Cita de: "nsL"No entendi bien eso de que multiplica por 2, si puedes explica un poco mas plz ;)
Veamos, cuando creas un vector tienes cierta memoria reservada para lo que contendrá, es decir, inicialmente tendrá un capacidad de n elementos ( creo que son 32, pero no me hagas mucho caso ) y al llenar esos n elementos con información te multiplica la capacidad total por 2. Esto puede ser una putada, imaginate si tienes cientos de elementos, puede que estes usando doble de memoria de la que quieres usar. Si usas 33 elementos, el vector te hará espacio para 64 con lo cual tienes 31 desaprobechados. Yo lo veo mas rentable aumentar cada 32 otros 32.

Respecto al problema, ¿porque no creas la estructura y le inicias todos los miembros y DESPUES la insertas en el vector?

nsL

 Es que en mi libro dice que si lo pones asi inicialmente esta vacio el vector y segun haces push agregas.
para hacerlo con un tamaño era algo asi: vector caca(32) como dices tu. igual es eso que dices qu antes era distinto y empezaba con un minimo de 32, eso ya no se :P

Respecto a lo de inicializar primero los parametros y luego agregar ya lo probe:


void CSprite::addframe(char *Path)
{
listaFram *Aux = (listaFram *)malloc(sizeof(listaFram));
frameList[++total].frame = IMG_Load(Path);
frameList.push_back(*Aux);
}


y era como lo tenia en un principio, pero asi no me mostraba el sprite. Fue cambiar el orden y empezar a verse el sprite. La verdad q no se donde puede estar el error :S de todas formas gracias por el interes ;)

Saludos!  B)  
Yo no muero hasta la muerte -

Warchief

Cita de: "nsL"
Citar
"total" empieza en -1?

Empieza en 0, y asigna a partir del 1. Es decir, frame 1, 2 ,3. Por eso primero incremento, pa posicionarlo en 1 para el primer frame y segun añada q lo meta en el siguiente hueco.
A eso me refería. Si haces:

main() {
...
miCSprite->add(sprite1);
...
}

No debería hacer:

frameList.push_back(*Aux);
frameList[0].frame = IMG_Load(Path);

?


En cualquier caso:

void CSprite::addframe(char *Path)
{
listaFram *Aux = (listaFram *)malloc(sizeof(listaFram));
frameList[++total].frame = IMG_Load(Path);
frameList.push_back(*Aux);
}


será


void CSprite::addframe(char *Path)
{
listaFram *Aux = (listaFram *)malloc(sizeof(listaFram));
Aux->frame = IMG_Load(Path);
frameList.push_back(*Aux);
}


No?

nsL

 si weno, el ultimo trozo q pusiste es como lo tenia, es que le di la vuelta pensando q era como lo tenia antes pero me equivoque.

respecto a los index del vector, sea cual sea el comienzo, ya sea 0 o 1,  no deberia dar error al cargar otro frame. en todo caso daria error al referenciarlo luego que te equivoques de frame...

de todas formas voy a probar a meter el primer frame en 0 y luego 1, 2, 3 y en 3 minutos edito y te cuento a ver..

PD: si lo pongo pa qu el primero lo meta en 0 no sale ni 1 frame :P
na este es el cuento de nunca acabar :P

Gracias de todas formas ;)
Yo no muero hasta la muerte -

Warchief

 Con el 0 me refería al caso de sprite1; quiero decir usar postincremento en lugar de preincremento.


Volvamos a:
void CSprite::addframe(char *Path)
{
listaFram *Aux = (listaFram *)malloc(sizeof(listaFram));
Aux->frame = IMG_Load(Path);
frameList.push_back(*Aux);
}


despues de addframe puedes acceder a miCSprite->frame bien? (IMG_Load devuelve puntero válido con memoria?, igual falla la carga).

nsL

 No, si lo pongo asi (en ese orden) como te dije no me carga bien (extraño la verdad), sin embargo si primero meto el Aux en el vector y luego relleno los campos si que va. Eso si, solo va el primer frame, los consecutivos da el puto parachute q me esta calentando a mi ya.

ya probe todas las combinaciones posibles respecto a preincremento, postincremento, poner total a 0 ,1 , asignar yo el array con 1 , 0 en vez de con total y nada de nada. Pero lo q me fastidia del tema es que seguro que es alguna parida del tipo for (i = 1; i==i ; i++) o similares, q me suelen tocar el alma cada poko.

He subido todo el codigo fuente a una web por si le quereis echar un ojo, no hace falta ni que compileis, es mirar por encima a ver si veis algo extraño, si quereis o teneis tiempo. sino da igual, si de todas formas poco me entero yo siendo mi codigo, vosotros tendreis q ver para q vale cada cosa y es mas tediosos, pero weno, ahi va:

Na, ahora se me cuelga el pc y no puedo subir el archivo al servidor, y el que subo esta corrupto. Ahora que, revienta el pc y la metralla me mata? porq ya a este paso...

http://usuarios.lycos.es/rage182/sdlbeg.rar
ó http://usuarios.lycos.es/rage182/sdlbeg.zip

a ver si conseguis bajarlo y no esta corrupto

Saludos!
Yo no muero hasta la muerte -

Sacrifai

 ¿Que versión de SDL usas?

nsL

 1.2.8, pero vamos, problema de SDL no es, porq hasta ahora con listas enlazadas conseguia tener varios frames (surfaces) por sprite, pero fue cambiar a vector y algo hago mal que no rula el tema.

ire pa la cama y mañana lo cogere con mas calma, aunq la verdad q como no consiga solucionarlo no se que narices voy a hacer.en fin... tamañana  :D

Yo no muero hasta la muerte -

samsaga2

 frameList es del tipo listaFram y tu estas haciendo push_back de variables del tipo *listaFram. Lo que quiere decir penchada al canto. Lo que me sorprende es que el compilador no se queje.

Warchief

 
Cita de: "samsaga2"frameList es del tipo listaFram y tu estas haciendo push_back de variables del tipo *listaFram. Lo que quiere decir penchada al canto. Lo que me sorprende es que el compilador no se queje.
El vector es de , pero Aux es , por eso hace *Aux al push.



@nsL

1) Lo que se me ocurre es que como es mem dinámica no situe los elementos del vector en direcciones continuas de memoria. Prueba a usar frameList.at(i) en vez de frameList.

2) Por ejemplo en el codigo del destructor de CSprite:

int i = 1;

while (i != total+1)
{
 SDL_FreeSurface(frameList[i].frame);
 free(frameList[i].frmask);
 i++;
}

Sigo pensando que sería desde 0; en el caso de std::vector::at también:

int i = 0;

while (0 != total)
{
 SDL_FreeSurface(frameList.at(i).frame);
 free(frameList.at(i).frmask);
               // no falta liberar la memoria del frameList.at(i) ? viene de un malloc
            i++;
}


(Es que no tengo sdl pa compilar).






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.