Extraño problemas con vector

Iniciado por amchacon, 11 Abril 2014, 00:14 AM

0 Miembros y 3 Visitantes están viendo este tema.

amchacon

Pues resulta que tenía petadas "aleatorias" en mi programa. Estuve mirando y comprobé que pasaba en la destrucción de un objeto.

El objeto tiene pocos atributos, lo unico que puede causar problemas es:
Código (cpp) [Seleccionar]
std::vector<std::vector<RGB> > Matriz;

RGB es una clase con 3 enteros. Eso no debería causar problemas.

Probé a depurar el destructor:
Código (cpp) [Seleccionar]
~Image()
{
   for (int i = 0; i < Matriz.size();i++)
       Matriz[i].clear();
   std::cout<<"Destruidas las filas..."<<std::endl;
   Matriz.clear();
   std::cout<<"^^"<<std::endl;
};


Falla en el ultimo clear. Pero no entiendo porque. ¿Hay problemas en destruir un vector desde otro vector?

Repito que no pasa siempre, solo pasa en X casos (y con la misma entrada y circunstancias :huh: :huh:).




Vale, esque escribía en posiciones negativas del vector *_*
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

ivancea96

Pero el destructor de vector ya destruye sus componentes por ti no? :o

amchacon

Cita de: ivancea96 en 12 Abril 2014, 13:18 PM
Pero el destructor de vector ya destruye sus componentes por ti no? :o
Ya lo sé, pero estaba depurando porque era super extraño.

Para la proxima vez usaré la funcion at en vez de los corchetes [] para adceder al vector. La función at lanza una excepción si adcedo fuera del rango, asi que me libro de estos problemas ^^
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

eferion

El problema de los corchetes es que si el índice no existe, el contenedor puede añadirlo automáticamente al hacer la consulta ( en los mapas al menos es así ).

Código (cpp) [Seleccionar]

#include <iostream>
#include <map>

int main( )
{
  std::map< int, int > datos;

  std::cout << datos.size( ) << std::endl;

  int numero = datos[ 3 ];

  std::cout << datos.size( ) << std::endl;
}


Una opción es usar, como has comentado, el método "at", que es de solo lectura. El problema es que te obliga a controlar las excepciones y en algunos entornos está mal visto.

El segundo método es lanzar un find para saber si posee ese índice ( en el caso de los vectores se puede hacer con size acordándose de controlar números negativos ) y, si el índice existe entonces recuperar el valor asociado.


amchacon

Cita de: eferion en 14 Abril 2014, 08:57 AM
El problema de los corchetes es que si el índice no existe, el contenedor puede añadirlo automáticamente al hacer la consulta ( en los mapas al menos es así ).
Bueno los maps es otra liga, en el vector no pasa eso.

Pero tampoco controla el indice que le metes, lo cual puede ser bueno si quieres máxima eficiciencia pero por otro lado...

Después de este error, he perdido mi confianza en los [] ;D

Cita de: eferion en 14 Abril 2014, 08:57 AMUna opción es usar, como has comentado, el método "at", que es de solo lectura. El problema es que te obliga a controlar las excepciones y en algunos entornos está mal visto.
No sé porque la gente odia tanto las excepciones de verdad, es una magnifica forma de depurar.

Pones throw "mensaje" en potenciales errores (archivo no encontrado, entrada invalida...) y envuelves las llamadas a las funciones con un try/catch. Si cualquiera de esas funciones tienen algún error, lo sabras enseguida, sin tener que comprobar funcion por función.

Cita de: eferion en 14 Abril 2014, 08:57 AMEl segundo método es lanzar un find para saber si posee ese índice ( en el caso de los vectores se puede hacer con size acordándose de controlar números negativos ) y, si el índice existe entonces recuperar el valor asociado.
A ver si te sigo... ¿Algo así?
Código (cpp) [Seleccionar]
map<int,int> Ejemplo;
//...

auto it = Ejemplo.find(4);

if (it != Ejemplo.end()) cout<<it->second<<endl;
else cout<<"No encontrado"<<endl;


No esta mal ^^
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

eferion

Cita de: amchacon en 14 Abril 2014, 11:19 AM
Bueno los maps es otra liga, en el vector no pasa eso.

Pero tampoco controla el indice que le metes, lo cual puede ser bueno si quieres máxima eficiciencia pero por otro lado...

Cierto, yo a veces hecho de menos contenedores un poco más "inteligentes" en este aspecto integrados en la stl. A veces es necesario reinventar la rueda.

Cita de: amchacon en 14 Abril 2014, 11:19 AM
Después de este error, he perdido mi confianza en los [] ;D

Jajajaja. No hace falta ser tan derrotista... el operador [] está muy bien... siempre y cuando no ser pierda de vista las implicaciones que tiene ( lo cual suele ser complicado ) XD

Cita de: amchacon en 14 Abril 2014, 11:19 AM
No sé porque la gente odia tanto las excepciones de verdad, es una magnifica forma de depurar.

Pones throw "mensaje" en potenciales errores (archivo no encontrado, entrada invalida...) y envuelves las llamadas a las funciones con un try/catch. Si cualquiera de esas funciones tienen algún error, lo sabras enseguida, sin tener que comprobar funcion por función.

Totalmente de acuerdo, pero también es cierto que es sencillo sentirse tentado a "abusar" del sistema y tirar siempre por el camino de las excepciones aún cuando no vienen a cuento.

Para mí una excepción debe lanzarse cuando la función no es capaz por sí misma de recuperar el error ( la conexión con la base de datos se ha cerrado, no se puede abrir un fichero, no hay privilegios para ejecutar una orden... ). Pero hay otras muchas cosas que no es necesario airear o que, directamente, es mejor diseñarlas de otra forma.

Además, no hay que olvidar que con un buen mecanismo de excepciones se puede extraer muchísima información útil. Pero como todo, es muy importante saber cuándo utilizarlas.

Cita de: amchacon en 14 Abril 2014, 11:19 AM
A ver si te sigo... ¿Algo así?
Código (cpp) [Seleccionar]
map<int,int> Ejemplo;
//...

auto it = Ejemplo.find(4);

if (it != Ejemplo.end()) cout<<it->second<<endl;
else cout<<"No encontrado"<<endl;


No esta mal ^^

Es un ejemplo muy gráfico e ilustrativo. Si bien tienes que añadir algo más de código y éste resulta algo más feo tiene algunas ventajas que, dependiendo del entorno, pueden ser bastante importantes:

* Consume menos memoria ( si sustituyes el segundo int del mapa por un objeto, evitas crear una instancia del mismo de forma innecesaria )... por este mismo motivo este mecanismo puede resultar incluso más rápido.

* Evitas llenar el mapa con guarrería ( a veces interesa tener en el mapa únicamente elementos con valor real ).

* Puedes incluir el código en un método "const".

* Puedes realizar acciones alternativas para el caso de que el índice no se encuentre sin añadir código adicional ( ya tienes que poner un if para comprobar el iterador )