Foros del Web » Programación para mayores de 30 ;) » C/C++ »

*** glibc detected *** double free or corruption (!prev): 0x0804b008 ***

Estas en el tema de *** glibc detected *** double free or corruption (!prev): 0x0804b008 *** en el foro de C/C++ en Foros del Web. Wenas de nuevo Estoy haciendo un programilla con c++ y al ejecutar sale todo bien, exceptuando un mensaje de error al final: *** glibc detected ...
  #1 (permalink)  
Antiguo 11/04/2006, 04:45
Avatar de fibergran  
Fecha de Ingreso: abril-2003
Ubicación: Jaén
Mensajes: 134
Antigüedad: 21 años, 8 meses
Puntos: 0
*** glibc detected *** double free or corruption (!prev): 0x0804b008 ***

Wenas de nuevo

Estoy haciendo un programilla con c++ y al ejecutar sale todo bien, exceptuando un mensaje de error al final:

*** glibc detected *** double free or corruption (!prev): 0x0804b008 ***
Abortado


el caso es que el compilador inserta un destructor al terminar el main

aki pongo el constructor y el destructor:

int_set_100::int_set_100(){
cursize = 0;
members = new int [50];
maxsize = 50;
}

int_set_100::~int_set_100 () {
delete [] members;
}


con este código me sale el error

*** glibc detected *** double free or corruption (!prev): 0x0804b008 ***
Abortado


pero si quito el delete ya no hay error y el programa va de maravilla, el problema es que si no pongo el delete no libero la memoria, cosa que estoy empeñado en hacer.

Si alguien me puede echar una mano, un cable o lo que sea
agradecido le stoy.

Merci de antemano

Por cierto la versión de linux es la suse 10.0
__________________
Visiten http://www.testsdetrafico.es
  #2 (permalink)  
Antiguo 11/04/2006, 12:18
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 20 años, 7 meses
Puntos: 74
Tal vez viendo el codigo completo podamos ayudarte mejor.
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
  #3 (permalink)  
Antiguo 12/04/2006, 05:35
Avatar de fibergran  
Fecha de Ingreso: abril-2003
Ubicación: Jaén
Mensajes: 134
Antigüedad: 21 años, 8 meses
Puntos: 0
inse100.C



/************************************************** **********
************************************************** ************
contenidos:
- Implementacion de int_set_100
- Implementacion de int_set_100_it


************************************************** ************

creacion: 8-03-96 (miguel vega)

modificaciones:

1) fecha (autor): 08-03-06 (Jaime Fuentes Pérez)

motivo: En la clase int_set_100, la función insert
devuelve el mismo valor cuando inserta el elemento
y cuando la tabla está llena, no es lo mismo que se
halla insertado bien el
elemento a que no se halla insertado bien.

mejoras: Añadir que cuando la tabla este llena devuelva
-1, quedando entonces:
-1 -> Tabla llena
0 -> El elemento ya pertenecia al conjunto
1 -> El elemento se inserto correctamente

2) fecha (autor): 21-03-06 (Jaime Fuentes Pérez)

motivo: En la funcion drop, borra la primera instancia
de ele que encuentra en el conjunto, y ya está.

mejora: Se ha hecho que se borre el elemento y se
desplacen todos una posición anterior, y se
decrementa cursize.

__________________________________________________ _

modificaciones práctica 2:

1) fecha (autor): 30-03-06 (Jaime Fuentes Pérez)

motivo: Con la clase anterior no se podían usar conjuntos de más
de 100 elementos

mejoras: Se utiliza memoria dinámica en el constructor, a la vez se crea
un destructor y se incluye este en el fichero cabecera intset.h
Además se incluye una variable maxsize como componente de la clase
con el objetivo de guardar la cantidad de memoria reservada para el
conjunto con la finalidad de hacer una clase mas eficiente en la reserva
de dicha memoria.

2) fecha (autor): 30-03-06 (Jaime Fuentes Peŕez)

motivo: Se busca más eficiencia en el insert de manera que no haya que
preguntar si el elemento a insertar ya existe en el conjunto. También
se busca la eficiencia en el drop.

mejoras: Se hace que en el insert unicamente se añada el elemento, indepen-
dientemente si ya estaba dentro o no, ademas de añadir a la función,
una parte en la que se reserve más memoria para el conjunto es el caso de
que ya esté llena la memoria reservada.

En el caso del drop, se busca primero un elemento distinto a ele
(elemento que se quiere eliminar), si no hay un elemento distinto a ele
significará que ele es el único elemento del conjunto (aunque puede estar
repetido), en este caso bastaría con poner cursize a 0. En el caso de que
exista un elemento distinto a ele, pondríamos este elemento en cada posición
en la que encontremos a ele.

3) fecha (autor): 06-04-06 (Jaime Fuentes Pérez)

motivo: Como pueden existir elementos repetidos dentro del vector, y con el
fin de utilizar el vector como un conjunto, necesitamos una fución que
nos de una posición ĺógica de cualquier elemento dentro del conjunto.

mejoras: Se añade una función miembro a la clase (indice) que se encargará de
devolver la posición lógica de ele dentro de el vector. La función es la
misma que index, aunque antes debemos de ordenar el conjunto

4) fecha (autor): 11-04-06 (Jaime Fuentes Pérez)

motivo: Como pueden existir elementos repetidos dentro del vector, y con el
fin de utilizar el vector como un conjunto, la función size, debe devolver
el tamaño lógico del conjunto, dado que un conjunto con los elementos:
<1 3 5 3 4 7> tendría 5 elementos y no 6.

mejora: A la función size le hacemos que elimine los elementos repetidos del
vector antes de devolver el tamaño del conjunto. Para esto crea un vector
auxiliar donde se copian todos los elementos del principal, y va metiendo
los elementos del vector auxiliar al principal dejando fuera los elementos
repetidos.

************************************************** ************
************************************************** ***********/
/************************************************** *****************

Implementacion:

Tad: int_set_100

Representacion:
Rep = int_set_100 data members:
{int cursize;
int maxsize;
int members[100];}
Rep r;

F.Abstraccion: r representa al conjunto de todos
los valores enteros de los primeros r.cursize
elementos de r.members y r.maxsize contiene
el numero de posicones reservadas para el
conjunto.

I.Representacion: entre los primeros r.cursize valores de
r.members no hay repeticiones

Descripcion:


Operaciones internas:
************************************************** *******************

Interface: int index(int ele)


requer.:
modif.:
efecto: si ele es uno de los valores contenidos en el array
devuelve el indice correspondiente, en caso contrario
devuelve el valor int(-1)


************************************************** *******************

Uso: is100pru.C contiene un ejemplo de uso

************************************************** *******************/
#include "intset.h"
#include <iostream.h>

int_set_100::int_set_100(){
cursize = 0;
members = new int [50];
maxsize = 50;
}

int_set_100::~int_set_100 () {
delete [] members;
}

int int_set_100::index(int ele){
for(int i = 0; i<cursize; i++) {
if (members[i] == ele)
return i;
}
return -1;
}

int int_set_100::insert(int ele){

if (cursize > maxsize) {
int* aux = members;
maxsize += 50;
members = new int [maxsize];
for (int i=0; i<cursize; i++)
members[i] = aux[i];
delete [] aux;
}



members[cursize++] = ele;
return 1;
}

int int_set_100::drop(int ele){
int i;
if ( index(ele) == -1)
return 0; //Si ele no esta ya sta to exo

// Busca dentro del conj un elem != a ele

int aux = 0;
bool modif_aux = false;
for (int z=0; (z < cursize) && (modif_aux == false); z++)
if (members [z] != ele){ //si encuentra un elem != ele salimos
modif_aux = true; //si no, seguimos hasta el final
aux = members [z];
}

// Reemplaza ele con aux
if (modif_aux == true)
while ( (i=index (ele)) != -1 ) {
members [i] = aux;
}

else //si modif_aux es true es xq solo queda un elem en el conj
cursize = 0;

return 1;
};

int int_set_100::member(int ele)
{return (index(ele) != -1);};

int int_set_100::size() {


int *aux;
int aux_cursize = cursize;
aux = new int [cursize];
for (int i=0; i < cursize; i++)
aux [i] = members [i]; //conj aux = a this

cursize = 0; // vaciamos el conj

//se insertan en el conj los elems sin repetir
for (int h=0; h< aux_cursize; h++)
if ((member (aux [h])) != 1) {
members [cursize] = aux [h];
cursize++;
}
delete [] aux;


return cursize;
};

int int_set_100::indice (int ele) {
int aux = size (); // para ordenar los elems del conjunto
for(int i = 0; i<cursize; i++) {
if (members[i] == ele)
return i;
}
return -1;

};
/************************************************** ******************

Implementacion:

Tad: int_set_100_it

Representacion:

Rep = int_set_100_it data members:

{int_set_100 set;int currindex;}

Rep r;


F.Abstraccion:

I.Representacion: una vez inicializado, al crear el objeto, set
no se modifica

Descripcion:


Operaciones internas:


Uso: is100pru.C contiene un ejemplo de uso

************************************************** *******************/


int_set_100_it::int_set_100_it (int_set_100 & aSet){
set = aSet;
currindex = 0;};

int int_set_100_it::operator++(int) {
return set.members[currindex++];
};

int int_set_100_it::atEnd() {
return (currindex == set.cursize);
};
__________________
Visiten http://www.testsdetrafico.es
  #4 (permalink)  
Antiguo 12/04/2006, 05:36
Avatar de fibergran  
Fecha de Ingreso: abril-2003
Ubicación: Jaén
Mensajes: 134
Antigüedad: 21 años, 8 meses
Puntos: 0
intset.h






#ifndef _intset100_h_
#define _intset100_h_

class int_set_100 {
int cursize; // num de posiciones ocupadas
int maxsize; // num de posiciones reservadas
int* members;

int index(int ele);
friend class int_set_100_it;
public:

int_set_100();
~int_set_100 ();
int insert(int ele);
int drop(int ele);
int member(int ele);
int size();
int indice (int ele);
};

class int_set_100_it {
int_set_100 set;
int currindex;

public:

int_set_100_it(int_set_100 & aSet);
int operator++(int);
int atEnd();};

#endif
__________________
Visiten http://www.testsdetrafico.es
  #5 (permalink)  
Antiguo 12/04/2006, 05:37
Avatar de fibergran  
Fecha de Ingreso: abril-2003
Ubicación: Jaén
Mensajes: 134
Antigüedad: 21 años, 8 meses
Puntos: 0
prueba2.C









#include <iostream.h>
#include "intset.h"

void printset(int_set_100 & set) {
int lc=0;
cout << "El conjunto tiene " << set.size() << " elementos: \n";

for (int_set_100_it j(set); !(j.atEnd()); )
{cout << j++ << ",";
if (++lc == 10) {cout << "\n"; lc = 0;};};
cout << "\n";
};

int main() {
int_set_100 a;
int i;

cout << "Se insertan del 0 al 20" << endl;
for (int i = 0; i<21; i++) a.insert(i);
printset(a);

cout << "Se insertan del 0 al 8" << endl;
for (int i = 0; i<9; i++) a.insert (i);
printset(a);


cout << "Se insertan 20 veces el 4" << endl;
for (i = 0;i<20; i++) a.insert(4); printset(a);

cout << "Se inserta el 143" << endl;
a.insert (143); printset (a);

cout << "Se elimina el 9" << endl;
a.drop (9); printset (a);


cout << "El tamaño del conj es: " << a.size () << endl;

cout << "La posición del 143 es: " << a.indice (143) + 1 << endl;

};
__________________
Visiten http://www.testsdetrafico.es
  #6 (permalink)  
Antiguo 12/04/2006, 05:39
Avatar de fibergran  
Fecha de Ingreso: abril-2003
Ubicación: Jaén
Mensajes: 134
Antigüedad: 21 años, 8 meses
Puntos: 0
Aquí les puse los 3 archivos impliados, es una práctia para la facultad, así que no es que tenga mucho sentido.

De todas formas ya la entregué, probé en otra máquina cn RED HAT 9 y no me daba el fallo.

Aun así me gustaria que me ayudasen con el problema porque la próxima práctica es una reforma de esta y me seguirá dando el mismo error, supongo.

Gracias
__________________
Visiten http://www.testsdetrafico.es
  #7 (permalink)  
Antiguo 12/04/2006, 07:20
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 8 meses
Puntos: 17
Bueno no he revisado el código, dudo que alguien lo haga :P

Puede que el problema venga de los objetos temporales que uses entre medio del camino. La verdad es que requiere práctica saber cuántos objetos se crean y se destruyen sin que te des cuenta.

El problema típico es que no hayas creado un constructor copia o operador de asignación adecuado y te lo haya hecho el compilador. ¿Lo has hecho?

Si no tienes un constructor copia, cuando hagas algo así:

objeto X(hola,15,12);
objeto Y = X;

se habrá llamado a 1 new (objeto X), y a 2 delete. Cuando haces "Y=X", el compilador copia la dirección del puntero de X a Y, resultando en que tienes dos objetos iguales, SÍ, pero apuntando al mismo contenido. Es decir, cuando se destruyan los objetos, eliminarás 2 veces la misma memoria.

Resultado: lo que te dice la glibc claramente: "double free", has liberado dos veces la memoria.

Lo mismo ocurre con el operador de asignación al tratar de hacer:

objeto X(hola,15,15);
objeto Y;
Y = X;

Tranquilo, es un error de novato que nos ha pasado a todos ;) Recuerda: Nunca dejes que el compilador cree el constructor copia / operador de asignación el sólo.

Algunos compiladores incluso permiten deshabilitar esa característica (estándar en C++), para que nunca te olvides de implementarlos.
  #8 (permalink)  
Antiguo 12/04/2006, 07:27
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 8 meses
Puntos: 17
Bueno he mirado el código, y efectivamente, no has implementado ni constructor copia ni operador de asignación, solo constructor y destructor. ;)
  #9 (permalink)  
Antiguo 12/04/2006, 12:45
Avatar de fibergran  
Fecha de Ingreso: abril-2003
Ubicación: Jaén
Mensajes: 134
Antigüedad: 21 años, 8 meses
Puntos: 0
ok

muchas gracias

no sabia que glibc double free saliese por haber liberado doblemente la memoria.

De hecho era la primera vez que veía este fallo


gracias x todo
__________________
Visiten http://www.testsdetrafico.es
  #10 (permalink)  
Antiguo 12/04/2006, 12:53
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 8 meses
Puntos: 17
Yo también, era la primera vez, pero como el mensaje se auto-explicaba, y es un error común tener problemas con la memoria al usar punteros con clases... Pues me imaginé que era el típico problema.

Hay dos maneras de resolver el problema:
1. Declarando (pero no implementando) el ctor copia y el operador =, para que nunca puedas copiar un objeto y nunca caigas en esos problemas, pero te quita mucha funcionalidad.
2. Implementando tú el ctor copia y el operador =. En tu caso, lo único que tienes que hacer es reservar una nueva memoria para la copia o la aisngación, y copiar el contenido al nuevo objeto. El destructor se encargará de destruir todas las memorias de todos los objetos.

En realidad, el compilador lo hace con buena intención y lo hace bien, pero si usas punteros, la cosa cambia. Es diferente el puntero que el contenido, y eso el compilador no lo puede manejar por ti.

También podrías no usar punteros directamente, usarlos inteligentes, o usar contenedores de la STL como std::vector.
  #11 (permalink)  
Antiguo 19/04/2006, 03:23
Avatar de carlosrdelmoral  
Fecha de Ingreso: agosto-2004
Mensajes: 149
Antigüedad: 20 años, 4 meses
Puntos: 0
Cita:
Iniciado por fibergran
Wenas de nuevo

Estoy haciendo un programilla con c++ y al ejecutar sale todo bien, exceptuando un mensaje de error al final:

*** glibc detected *** double free or corruption (!prev): 0x0804b008 ***
Abortado


el caso es que el compilador inserta un destructor al terminar el main

aki pongo el constructor y el destructor:

int_set_100::int_set_100(){
cursize = 0;
members = new int [50];
maxsize = 50;
}

int_set_100::~int_set_100 () {
delete [] members;
}


con este código me sale el error

*** glibc detected *** double free or corruption (!prev): 0x0804b008 ***
Abortado


pero si quito el delete ya no hay error y el programa va de maravilla, el problema es que si no pongo el delete no libero la memoria, cosa que estoy empeñado en hacer.

Si alguien me puede echar una mano, un cable o lo que sea
agradecido le stoy.

Merci de antemano

Por cierto la versión de linux es la suse 10.0

Yo hace años que no toco el c++ ,pero se me paso algo por la cabeza , aunque no me he molestado en probarlo e igual el compilador no lo traga, se trata de decirle el tipo de array que vas a borrar para que la memoria que eliminas tenga el tamaño adecuado mediante un cast.

delete [] (int) members;

Ora cosa es revisar que tengas como propiedad declarado como array entero a a member antes de instanciarlo.

Pero no me hagas mucho caso , ya son años que no toco los objetos..

Pruebalo igual te va.

Saludos,
__________________
Webmasters
  #12 (permalink)  
Antiguo 19/04/2006, 07:14
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 8 meses
Puntos: 17
Cita:
Iniciado por carlosrdelmoral
Yo hace años que no toco el c++ ,pero se me paso algo por la cabeza , aunque no me he molestado en probarlo e igual el compilador no lo traga, se trata de decirle el tipo de array que vas a borrar para que la memoria que eliminas tenga el tamaño adecuado mediante un cast.

delete [] (int) members;

Ora cosa es revisar que tengas como propiedad declarado como array entero a a member antes de instanciarlo.
No tiene nada que ver con un cast. Soltaría un warning (lo más probable), además de que "members" es "int *", así que no hace falta ningún código sucio para eso.

por otra parte, no sería "delete [] (int) members", sino:

"delete [] static_cast<int *>(members)"

Sí, members está declarado como "int *".
  #13 (permalink)  
Antiguo 21/04/2006, 09:05
Avatar de carlosrdelmoral  
Fecha de Ingreso: agosto-2004
Mensajes: 149
Antigüedad: 20 años, 4 meses
Puntos: 0
De acuerdo

Bueno , ahora ya vi por que lo dices..

Pero no hace falta que te lo tomes tan a pecho!! yo lo dije para intentar dar una idea de lo que podria probar.

Un poco mas y me sacas una escopeta. joe

No se si tan a pecho te tomas ese tema vendria bien hacer tutoriales para la gente, y de esa forma tener online ejemplos de casos que sucedan en el foro para ayudar. (idea).
__________________
Webmasters
  #14 (permalink)  
Antiguo 21/04/2006, 12:37
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 8 meses
Puntos: 17
Cita:
Iniciado por carlosrdelmoral
Bueno , ahora ya vi por que lo dices..

Pero no hace falta que te lo tomes tan a pecho!! yo lo dije para intentar dar una idea de lo que podria probar.

Un poco mas y me sacas una escopeta. joe

No se si tan a pecho te tomas ese tema vendria bien hacer tutoriales para la gente, y de esa forma tener online ejemplos de casos que sucedan en el foro para ayudar. (idea).
Perdona no iba a mal, simplemente contesto a la dudas lo más objetivamente posible.

Muchas veces parecen rapapolvos, lo sé, pero no es la intención, sino la de ayudar ;)
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:07.