Como puedo depurar un fallo de asignacion de memoria en C++???

Iniciado por kafok, 9 Noviembre 2014, 19:55 PM

0 Miembros y 1 Visitante están viendo este tema.

kafok

Pffff.... al fina que tonteria era, yo creia (habia leido) que los al quitar los privates en este tipo de situaciones no pasaba nada porque al cliente solo le interesa la interfaz por asi decirlo, pero no...

Lo que propone esta pagina su primera sugerencia lo tuve en mente a la hora del diseño de mi libreria, incluso tenia un diseño pensado para hacerle al usuario mas ameno todo en vez de tener que importar a mano la funciones que devuelvan los objetos, pero, pierdo la herencia entre clases de mi dll y clases del cliente que cree mi cliente heredando de la clases, eso no seria posible, ni tampoco casting a traves de constructores, cosas de las cuales no puedo prescindir segun las necesidades de mi problema en cuestion.

Lo primero que se me ocurrio al ver el problema, y conociendo las posivilidades que tengo es obtener el tamaño de la clase con sizeof y declarar en el (.h) del cliente como privado algo tal que:

Código (cpp) [Seleccionar]
private:
   char size[/*Aqui lo que devuelva sizeof*/];


Pero la verdad, es bastante chapucero, y tendria que tener cuidado, no es bueno trabajar con numeros magicos. La segunda opcion no la conocia, esta claro que es mi salvacion!! Pero haber entiendo que la parte que pone:
Código (cpp) [Seleccionar]
* : smile(new CheshireCat())

sea equivalente a poner:
Código (cpp) [Seleccionar]
smile = new CheshireCat();

como primera linea en el constructor de turno, pero esto:
Código (cpp) [Seleccionar]
: smile(new CheshireCat(*other.smile))

Es en el constructor copia, el compilador genera automaticamente un constructor copia para el struct?

Ante todo, muchisimas gracias Eternal Idol, no hubiera llegado yo solo a todas esas conclusiones por desconocimiento. Gracias

Eternal Idol

#31
http://en.cppreference.com/w/cpp/language/initializer_list

El constructor copia es equivalente a:
Código (c++) [Seleccionar]
Handle::Handle(const Handle& other)
{
   smile  = new CheshireCat(*other.smile);
   // do nothing
}


http://en.wikipedia.org/wiki/Copy_constructor

Si, pero ese constructor copia implicito como explica en el enlace de arriba tendria el problema del shallow copy, por eso esta implementado.

Por ejemplo, esto explotaria al llegar al destructor de Handle con el objeto x donde intentaria liberar smile (que apuntaria a la memoria ya liberada al llamar al operador delete con el objeto p).
Código (c++) [Seleccionar]
Handle *p = new Handle;
Handle x = *p;
delete p;


De nadas  ::)
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kafok

Y vuelven los problemas, aqui hay sitio para todos! vale, no!

Redefini la clase Miclase de la siguiente forma:

Código (cpp) [Seleccionar]
class DLL_EXPORT Miclase
{
    private:
        struct OpaquePointer;
        OpaquePointer *op;

    public:
        Miclase();
        ~Miclase();
};


y en el .cpp:

Código (cpp) [Seleccionar]
struct Miclase::OpaquePointer
{
    string str;
};

Miclase::Miclase() : op(new OpaquePointer())
{
    op->str.clear();
}

Miclase::~Miclase()
{
    delete op;
}


y mi codigo cliente:

Código (cpp) [Seleccionar]
int main()
{
    Miclase ss[21];
    ss[0] = Miclase(); /* AQUI! */
    system("pause");

    return 0;
}


La linea que señalo es la que me da problemas, en mi codigo uso la funcion que me recomendaros en este hilo hace tiempo: SetUnhandledExceptionFilter. Y me salta la excepcion, pero si no pongo nada como es el caso del codigo de arriba habria que depurar para darse cuenta de que se lanza una excepcion. La excepcion salta en el destructor del elemento al que se le vuelve a llamar un construnctor por defecto. Depurando paso a paso con mi IDE, en esa linea confilctiva se llama al destructor y se vuelve a construir el nuevo. Si quito la linea y miro para otro lado no pasaria nada, pero hay hay un problema y no se cual es.

Tambien he intentado usar HeapAlloc en vez de new para OpaquePointer pero cada vez que hago alguna operacion con str como el clear crashea, eso si me imagino que habra que personalizar un Allocator pero no estoy seguro de porque falla, solo es una suposicion.

Eternal Idol

#33
ss[0] = Miclase();   /* AQUI! */

No entiendo para que haces eso sinceramente ... ya tenes 21 objetos inicializados correctamente ... ¿Queres crear un objeto temporal y asignarlo/copiarlo en el primer elemento del array? Para que no falle sobrecarga el operador de asignacion como muestra el ejemplo ...

PD. Quiero creer que estas incluyendo la unica definicion que mostras tal cual en el ejecutable.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kafok

Ese codigo era de un test de hace tiempo, lo hice asi porque para probar despues constructores con new solo tenia q poner asterisco en la declaracion y poner el new delante asi: ss[0] = new Miclase();

Vale, al tiempo me di cuenta de que el constructor por defecto ahi era una tonteria, pero bueno, resulto que por el simple hecho de estar ahi falla. Se supone que tiene que fallar? Si es asi, ¿Como debo sobrecargar el operadir de asignacion?

Y que hago para que no falle con HeapAlloc, en vez de new,¿Tengo que definor un Allocator o que? Me interesaria tenerlo todo en el mismo heap.

Eternal Idol

Si, pero eso si tiene sentido, si uno tiene punteros a objetos entonces tiene que crear los objetos ...

En fin, en el articulo de la Wikipedia esta sobrecargado, aca tenes las declaracion para tu clase, implementalo en base al articulo:

Código (cpp) [Seleccionar]
Miclase& Miclase::operator=(const Miclase &other);

No se que otro fallo tendras ahora, en el ultimo codigo que dejaste con la sobrecarga mencionada no hay ningun fallo.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kafok

aaaaaaaaa!! vale vale, sobrecargue el operador = tal y como dice la pagina, ya entiendo todos los errores que me salian. Es que no entendi muy bien porque sobrecargaba ese operador en la pagina, lo estuve mirando con calma y ya entendi el porque sobrecargarlo, y ya se porque fallaba en ese fragmentito de codigo y mas fallos que daba en mi programa real.

Ya funciona bien!! mi dll ya no da problemas!! a costado, pero al fin fucnionaaaaa!!

Muchisimas gracias

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón