2010-04-29 9 views
7

Creé una estructura para contener algunos datos y luego declare un vector para mantener esa estructura.segfault en el vector <struct>

Pero cuando hago un push_back me sale maldito segfault y no tengo ni idea de por qué!

Mi estructura es define como:

typedef struct Group 
{ 
    int codigo; 
    string name; 
    int deleted; 
    int printers; 
    int subpage; 

    /*included this when it started segfaulting*/ 
    Group(){ name.reserve(MAX_PRODUCT_LONG_NAME); } 
    ~Group(){ name.clear(); } 
    Group(const Group &b) 
    { 
    codigo = b.codigo; 
    name = b.name; 
    deleted = b.deleted; 
    printers = b.printers; 
    subpage = b.subpage; 
    } 
    /*end of new stuff*/ 
}; 

Originalmente, la estructura no tenía la copia, constructor o destructor. Los agregué más tarde cuando leí esta publicación a continuación.

Seg fault after is item pushed onto STL container

pero el resultado final es el mismo.

¡Hay uno que me está molestando! Cuando primero introduzco algunos datos en el vector, todo va bien. ¡Más adelante en el código cuando intento introducir más datos en el vector, mi aplicación simplemente falla!

El vector se declara

vector<Group> Groups 

y es una variable global para el archivo donde lo estoy usando. No hay ningún otro lugar los externos, etc ...

puedo rastrear el error a:

_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage- this->_M_impl._M_start); 

en vector.tcc cuando termino de la adición/copiar el último elemento al vector ....

Por lo que puedo decir. No debería necesitar nada que ver con un constructor de copias, ya que una copia superficial debería ser suficiente para esto. Ni siquiera estoy asignando espacio (pero reservé la secuencia para probar).

¡No tengo idea de cuál es el problema!

estoy corriendo este código en OpenSuse 10.2 con gcc 4.1.2

No estoy realmente a ansiosos por mejorar gcc debido a problemas de compatibilidad hacia atrás ...

Este código funcionó "perfectamente" en mi máquina de Windows. Lo compilé con gcc 3.4.5 mingw sin ningún problema ...

ayuda!

--- ... ---

::: ::: EDITAR

empujo datos

Group tmp_grp; 

(...) 

tmp_grp.name = "Nova "; 
tmp_grp.codigo=GetGroupnextcode(); 
tmp_grp.deleted=0; 
tmp_grp.printers=0; 
tmp_grp.subpage=0; 
Groups.push_back(tmp_grp); 
+1

Mostrar el código que lo empuja por favor. –

+1

Su estructura no necesita el constructor de copia, y es una mala idea proporcionarla: el constructor de copia predeterminado hace todo lo que necesita. Tampoco necesita el typedef en la estructura.Tampoco necesita el destructor, y probablemente no el constructor que toma un tamaño. –

+0

@Neil. ¡Lo sé! Los agregué por "desesperación" –

Respuesta

0

Bueno ...

valgrind to the rescue! Lo que me llamó la atención en el registro valgrind fue esta pieza.

Invalid write of size 4 
==4639== at 0x805BDC0: ChangeGroups() (articles.cpp:405) 
==4639== by 0x80AC008: GeneralConfigChange() (config.cpp:4474) 
==4639== by 0x80EE28C: teste() (main.cpp:2259) 
==4639== by 0x80EEBB3: main (main.cpp:2516) 

En este punto en el archivo que estaba haciendo este

Groups[oldselected].subpage=SL.selected_code(); 

y lo que si oldselected estaba fuera de los límites del vector?

En este caso lo que estaba ocurriendo era que oldselected podría ser -1 ... y aunque esto no fue estrellarse en este punto, que estaba escribiendo algo en otro lugar ...

probablemente debería empezar a utilizar el at() operador y compruebe la excepción o simplemente compruebe si "oldselected" es> 0 y < Groups.size() [preferred solution].

Felicitaciones a John y Josh por recordarme valgrind.

Lo he usado antes, pero nunca tuve que hacer nada significativo con él (afortunadamente: D).

Es interesante que en Windows no obtengo esta segfault. El problema era el mismo ... Supongo que tiene algo que ver con la administración de la memoria y el compilador ... realmente me elude.

Gracias a todos por la entrada;)

Saludos

1

Definitivamente debe eliminar el destructor. C++ llamará automáticamente al destructor de todos los miembros de datos, y hacer cosas a los miembros que ya tienen un destructor como ese es innecesario y podría ser inseguro.

Pero, no veo nada malo con su código per se. Tendrás que publicar un poco más de eso. Intenta expandir la sección (...) - muéstranos todo el código que involucra el vector.

6

como Neil Dicho esto, no es necesario un constructor por defecto, constructor de copia, o destructor:

  • std::string limpia después de sí mismo, por lo que su destructor no es necesario.
  • El constructor de copia superficial provisto por el compilador funcionará muy bien.
  • std::string::reserve es innecesario, ya que std::string asignará dinámicamente memoria según sea necesario, pero puede proporcionan un beneficio de rendimiento.

El código que ha publicado parece correcto (y se ve muy simple y sencillo, por lo que es difícil ver dónde podría aparecer un error). Por lo tanto, sospecho que está corrompiendo la memoria en otro lugar de su código y que el vector<Group> es simplemente la víctima.

Pruebe la instalación de Valgrind (OpenSuse debe proporcionar un paquete para ello) y ejecute su aplicación a través de él (desde la línea de comandos, simplemente ejecute valgrind my-app) para ver si Valgrind puede detectar cualquier daño en la memoria.

1

Los errores de memoria como este pueden deberse a que se borró la misma memoria dos veces o se borró la memoria que no se obtuvo de la nueva. Los errores a menudo ocurren mucho después del hecho en lugares como este. Como DeadMG ya declaró, instale valgrind y busque otros problemas de memoria aparentemente no relacionados.

Cuestiones relacionadas