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

[SOLUCIONADO] Como eliminar una clase de una array dinamica

Estas en el tema de Como eliminar una clase de una array dinamica en el foro de C/C++ en Foros del Web. Hola chicos soy nuevo en C++ y tengo un problema con una array dinamica que hice, lo que hice fue crear una clase que almacene ...
  #1 (permalink)  
Antiguo 03/10/2014, 14:55
Avatar de Andrek  
Fecha de Ingreso: enero-2012
Mensajes: 14
Antigüedad: 12 años, 9 meses
Puntos: 1
Como eliminar una clase de una array dinamica

Hola chicos soy nuevo en C++ y tengo un problema con una array dinamica que hice, lo que hice fue crear una clase que almacene la array dinamica y crear funciones para modificar esa array a mi gusto (agregar, ver, eliminar, etc.) y la función eliminar no sirve me ayudan por favor?

Código:
#include<iostream>

using namespace std;

class A
{
      int n;
      public:
      A() { n = 0; }
      int GetN() { return n; }
      int SetN(int new_n) { n = new_n; }
};

class Vector_A
{
      A** array;
      int size;
      public:
      Vector_A() { array = new A*; size = 0; }
      int Size() { return size; }
      void agregar(A *a)
      {
           size++;
           array[size] = a;
      }
      void eliminar(int index)
      {
           if (index > 0 && index <= size)
           {
                for(int i = index; i <= size; i++)
                {
                        if (i + 1 <= size)
                        {
                             array[i] = array[i + 1];
                             //array[index + 1] = eliminated;
                        } else {
                               //array[index] = eliminated;
                        }
                }
                size--;
           }
      }
      A* ver(int index)
      {
              //if (index > 0 && index <= size) { return array[index]; }
              return array[index];
      }
      void liberar()
      {
           delete[] array;
      }
};

void asignar(Vector_A *vector_a)
{
     for(int i = 1; i <= vector_a->Size(); i++)
     {
             vector_a->ver(i)->SetN(i * 20);
     }
}

void ver(Vector_A *vector_a)
{
     for(int i = 1; i <= vector_a->Size(); i++)
     {
             vector_a->ver(i)->SetN(i * 20);
             cout << i << ": " << vector_a->ver(i)->GetN() << endl;
     }
}

int main()
{
    Vector_A vector_a;
    A a, b, c;
    vector_a.agregar(&a);
    vector_a.agregar(&b);
    vector_a.agregar(&c);
    asignar(&vector_a);
    ver(&vector_a);
    vector_a.eliminar(1);
    ver(&vector_a);
    cout << "3: " << vector_a.ver(3)->GetN() << endl;
    vector_a.liberar();
    system("PAUSE");
    return 0;
}
  #2 (permalink)  
Antiguo 05/10/2014, 05:42
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Como eliminar una clase de una array dinamica

Código C++:
Ver original
  1. class Vector_A
  2. {
  3.       A** array;
  4.       int size;
  5.  
  6.   public:
  7.       Vector_A() { array = new A*; size = 0; }
  8.       int Size() { return size; }
  9.       void agregar(A *a)
  10.       {
  11.            size++;
  12.            array[size] = a;
  13.       }

En el constructor estás creando un arreglo a punteros pero no has definido un tamaño para ese arreglo luego, legalmente, solo te va a permitir agregar un puntero, puedes meter más pero no estarás pisando memoria que no le corresponde al arreglo y tendrás fallos inesperados.

El funcionamiento que se debería esperar es el siguiente (es un ejemplo, admite modificaciones ):

* Al construir la clase, dado que no tiene elementos, puedes dejar el "array" apuntando a null o crear el array con un tamaño predefinido por defecto.

* Al agregar un elemento tienes que comprobar si "array" admite más elementos o no. Si los admite, añades el nuevo puntero a la lista. Si no entran más elementos tienes que crear un nuevo "array" con más tamaño, copiar los elementos del array viejo al nuevo y borrar el viejo (como el array es de punteros éstos no se ven afectados). Hay que tener en cuenta que "array" puede apuntar a null.

Para poder comprobar si entran o no más elementos en "array" necesitas una nueva variable que te indique la capacidad máxima de "array" en todo momento.

No te he puesto código porque creo que es mejor que primero lo intentes por tu cuenta, pero si no te sale siempre puedes comentar el punto donde te has quedado atascado.

Un saludo.
  #3 (permalink)  
Antiguo 05/10/2014, 17:20
Avatar de Andrek  
Fecha de Ingreso: enero-2012
Mensajes: 14
Antigüedad: 12 años, 9 meses
Puntos: 1
Respuesta: Como eliminar una clase de una array dinamica

Gracias por contestar!

Empece desde 0 asi que cambie los nombres de clases y funciones. Ya me funciono agregandole al constructor:

Código:
Vector_Digit() { array = new Digit*[5]; array_size = 5; size = 0; }
Y probe a agregar mas elementos de lo asignado y me dio problemas como dijiste, trate de agrandar el array pero no pude :S aqui te dejo lo que intente hacer:

Código:
//* Problema al crear la nueva array.
           if (size + 1 > array_size)
           {
                    int new_array_size = (array_size / 5) * 5 + 5; // El tamaño va a ir aumentando 5 en 5.
                    Digit** new_array = new Digit*[size]; // Array momentaneo.
                    
                    // Copiar los elementos del viejo array al array momentaneo.
                    for(int i = 0; i < size; i++)
                    {
                            new_array[i] = array[i];
                    }
                    
                    delete[] array; // Eliminar el antiguo array.
                    Digit** array = new Digit*[new_array_size]; // Recrear el viejo array con nuevo tamaño.
                    
                    // Copiar los elementos del array momentaneo al array recreado.
                    for(int i = 0; i < size; i++)
                    {
                            array[i] = new_array[i];
                    }
                    
                    delete[] new_array; // Eliminar array momentaneo.
                    array_size = new_array_size;
           }
           //*/
y te dejo todo el nuevo codigo:

Código:
#include <iostream>

using namespace std;

class Digit
{
      int number;
      public:
      void set(int new_number)
      {
           number = new_number;
      }
      int get()
      {
          return number;
      }
};

class Vector_Digit
{
      Digit** array;
      int array_size;
      int size;
      public:
      Vector_Digit() { array = new Digit*[5]; array_size = 5; size = 0; }
      int Size() { return size; }
      void push_back(Digit *digit)
      {
           //* Problema al crear la nueva array.
           if (size + 1 > array_size)
           {
                    int new_array_size = (array_size / 5) * 5 + 5; // El tamaño va a ir aumentando 5 en 5.
                    Digit** new_array = new Digit*[size]; // Array momentaneo.
                    
                    // Copiar los elementos del viejo array al array momentaneo.
                    for(int i = 0; i < size; i++)
                    {
                            new_array[i] = array[i];
                    }
                    
                    delete[] array; // Eliminar el antiguo array.
                    Digit** array = new Digit*[new_array_size]; // Recrear el viejo array con nuevo tamaño.
                    
                    // Copiar los elementos del array momentaneo al array recreado.
                    for(int i = 0; i < size; i++)
                    {
                            array[i] = new_array[i];
                    }
                    
                    delete[] new_array; // Eliminar array momentaneo.
                    array_size = new_array_size;
           }
           //*/
           array[size] = digit;
           size++;
      }
      void eliminate(int index)
      {
           if (index > -1 && index < size)
           {
                for(int i = index; i < size; i++)
                {
                        if (i + 1 <  size) { array[i] = array[i + 1]; }
                }
                size--;
           }
      }
      Digit* get(int index)
      {
             return array[index];
      }
      void free() { delete[] array; }
};

void ver(Vector_Digit *vector)
{
     for(int i = 0; i < vector->Size(); i++)
     {
             cout << i << ": " << vector->get(i)->get() << endl;
     }
}

void asignar(Vector_Digit *vector)
{
     for(int i = 0; i < vector->Size(); i++)
     {
             vector->get(i)->set(i * 5);
     }
}

int main(int argc, char *argv[])
{
    Vector_Digit vector;
    Digit digit1, digit2, digit3, digit4, digit5, digit6, digit7, digit8, digit9, digit10;
    
    vector.push_back(&digit1);
    vector.push_back(&digit2);
    vector.push_back(&digit3);
    vector.push_back(&digit4);
    vector.push_back(&digit5);
    //* Problemas al agregar.
    vector.push_back(&digit6);
    vector.push_back(&digit7);
    vector.push_back(&digit8);
    vector.push_back(&digit9);
    vector.push_back(&digit10);
    //*/
    
    asignar(&vector);
    ver(&vector);
    vector.eliminate(3);
    ver(&vector);
    
    system("PAUSE");
    vector.free();
    return EXIT_SUCCESS;
}
Gracias por la atencion!
  #4 (permalink)  
Antiguo 06/10/2014, 00:49
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Como eliminar una clase de una array dinamica

Código C++:
Ver original
  1. int new_array_size = (array_size / 5) * 5 + 5; // El tamaño va a ir aumentando 5 en 5.

Si tu intención es aumentar el tamaño del array de 5 en 5 no es mas fácil hacer simplemente una suma??

Código C++:
Ver original
  1. array_size += 5; // El tamaño va a ir aumentando 5 en 5.

Y luego, en el algoritmo que incrementa el tamaño del arreglo estás trabajando el doble de lo necesario. Dado que tanto "array" como "new_array" son punteros dobles, es decir, la variable únicamente almacena una dirección de memoria, puedes copiar dicho valor de una variable a otra. No es necesario copiar dos veces la lista de elementos:

Código C++:
Ver original
  1. if (size + 1 > array_size)
  2. {
  3.   array_size += 5; // El tamaño va a ir aumentando 5 en 5.
  4.   Digit** new_array = new Digit*[array_size];
  5.  
  6.   // Copiar los elementos del viejo array al array nuevo.
  7.   for(int i = 0; i < size; i++)
  8.   {
  9.     new_array[i] = array[i];
  10.   }
  11.  
  12.   delete[] array; // Eliminar el antiguo array.
  13.  
  14.   array = new_array; // Se copia el array.
  15. }
  #5 (permalink)  
Antiguo 07/10/2014, 07:44
Avatar de Andrek  
Fecha de Ingreso: enero-2012
Mensajes: 14
Antigüedad: 12 años, 9 meses
Puntos: 1
Respuesta: Como eliminar una clase de una array dinamica

Muchas gracias amigo por contestar!

Código:
int new_array_size = (array_size / 5) * 5 + 5; // El tamaño va a ir aumentando 5 en 5.
Lamento esto pero es que soy nuevo y estaba probando las matematicas de c++ y olvide acomodarlo.

Me ha servido todo a la perfeccion pero aun tengo una duda, al final del codigo no puedo liberar el array momentaneo porque 'array' ahora es un puntero que señala al array momentaneo cierto? y al usar 'delete[] array' estoy liberando tambien el array momentaneo, si es asi entonces al final termino usando es 'new_array' para almacenar las direcciones.

Te agradezco mucho tu tiempo, eres genial! Gracias!
  #6 (permalink)  
Antiguo 07/10/2014, 08:38
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Como eliminar una clase de una array dinamica

Cita:
Iniciado por Andrek Ver Mensaje
Muchas gracias amigo por contestar!
Me ha servido todo a la perfeccion pero aun tengo una duda, al final del codigo no puedo liberar el array momentaneo porque 'array' ahora es un puntero que señala al array momentaneo cierto?
Cierto, la línea "array = new_array" copia la dirección de memoria donde se encuentra la memoria reservada, por lo que a partir de ese momento ambos punteros están accediendo a la misma reserva de memoria.

Cita:
Iniciado por Andrek Ver Mensaje
... y al usar 'delete[] array' estoy liberando tambien el array momentaneo ...
exacto.

Cita:
Iniciado por Andrek Ver Mensaje
... si es asi entonces al final termino usando es 'new_array' para almacenar las direcciones.
Sí y no. A ver, "new_array" únicamente "existe" dentro de la función que lo ha declarado. Es decir, fuera de la función "push_back" no existe esta variable, por lo que no tiene ningún sentido hablar de ella.

Sin embargo, "array" si sigue existiendo fuera de esta función y, dado que has hecho que esta variable apunte a una reserva de memoria válida, permites que "array" pueda seguir almacenando lo que le vayas pasando.
  #7 (permalink)  
Antiguo 07/10/2014, 08:53
Avatar de Andrek  
Fecha de Ingreso: enero-2012
Mensajes: 14
Antigüedad: 12 años, 9 meses
Puntos: 1
Respuesta: Como eliminar una clase de una array dinamica

Cita:
Sin embargo, "array" si sigue existiendo fuera de esta función y, dado que has hecho que esta variable apunte a una reserva de memoria válida, permites que "array" pueda seguir almacenando lo que le vayas pasando.
Esto si que me termino de ayudar a entender el uso de 'new', bueno esta solucionado el tema.

Muchas gracias.

Etiquetas: clase, dinamica, funcion, int, vector
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

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 09:39.