[C con Clase] Vector de tamaño indef, definido en metodo.

Gilberto Cuba Ricardo gilberto.cuba en ucp.ho.rimed.cu
Vie Nov 19 01:05:20 CET 2010


Hola Jorge,

Jorge Vega Sanchez escribió:

> Creo que lo mejor es hacerlo con memoria dinamica. Pero aun así no
> me termina de funcionar el ejemplo.

:)

Bueno, esto es a gusto de consumidor, pero si lo prefieres así,
veamos entonces la situación.

> #include <stdio.h>


Estas dos líneas no nos van a hacer falta, por lo que podemos
eliminarlas.

> #include <vector>
> using namespace std;


> void metodo(int*);

> int main()
> {
>         int *array;
>         array = new int;
>                         
>         metodo(array);
>         
>         printf("Tercer valor del vector: %d \n", array[2]);
>         
>         delete[] array;
>         
>         return 0;
> }
>         
> void metodo(int* vector)
> {
>         int N=5;
>         
>         vector = new int[N];
>         for(int i=0; i<5; i++)
>         {
>                 vector[i]=i+5;
>         }
>         printf("Valores del vector: %d, %d, %d, %d y %d
> \n",vector[0],vector[1],vector[2],vector[3],vector[4]);
> }

Evidentemente tienes un problema, y yo diría más conceptual que de
programación. No sabría explicarte a ciencia cierta qué es realmente
lo que sucede y por qué es que se pierde el valor, sin embargo,
trataré de darte mi punto de vista y una solución al problema.

Lo primero es tratar de diseñar bien lo que uno necesita y hacerlo por
pasos lógicos, digamos que en tu ejemplo tienes un problema donde estás
dando una dimensión de un elemento a la variable "array" en el programa
principal. Sin embargo, cuando entras a "metodo", vector va a apuntar
a la misma dirección de memoria que array, porque está pasando el
valor por copia, por lo que cuando reservas los 5 enteros, lo hace bien
para "vector", pero ¿quién nos garantiza que "array" podrá alcanzarlos,
si es que están apuntando a el mismo espacio de memoria y si es acaso
consecutivo un valor del otro? (no me crean, invento esto, que me
rectifiquen los que saben :-))

Es por esto que cuando sale del método y tratamos de resolver la
posición dos de "array", no es alcanzada correctamente, porque este se
creo con un solo elemento y que no apuntan necesariamente a los de la
variable "vector" dentro de la función "metodo", y donde
evidentemente, se nos está quedando un trozo de memoria ahí sin
liberar, aunque digamos luego que el SO se encarga del trabajo sucio.
Sin embargo, si retornáramos a "vector" con:

return vector;

entonces el valor devuelto por esta función sí sería un arreglo de 5
elementos con los valores que se le asignaron.

Según algunas ideas que he ido perfeccionando en este tiempo, lo mejor
sería hacernos nuestro propio tipo, digamos que lo que necesitamos es
un arreglo dinámico de enteros, entonces definiríamos:

typedef int* int_array;

y luego trabajaría en función de él, ¿que por qué? pues porque uno se
enreda mucho con el lío de los punteros, y donde se piensa que va uno
simple entonces van dos y cuando es conveniente una referencia y
puntero, entonces metemos la pata y se arma el fanguero. :)

Entonces una propuesta a algo de lo que estás haciendo, es el
siguiente código, que no hace lo mismo que el tuyo, pero me imagino
que te puede ayudar. Este lo he hecho a base de &, para que
el paso del valor sea por referencia, pero se puede hacer también con
punteros, pero eso es tarea tuya ya, porque yo paso mi trabajo también
en hacerlo ;-)


#include <stdio.h>

typedef int* myarray;

int
  N = 5,
  top = 0;

void
constructor(myarray &v, int size = 5)
  {
    v = new int[size];
  }

void
destructor(myarray &v)
  {
    if(v)
      delete [] v;
  }

void
push_value(myarray &v, int value = 0)
  {
    v[top++] = value;
  }

int
get_value(myarray &v, int pos)
  {
    if(!v)
      return 0;

    return v[pos];
  }

int
main()
  {
    myarray array;

    constructor(array, N);

    for(int i = 0; i < N; ++i)
      push_value(array, i * 5);

    for(int i = 0; i < N; ++i)
      printf("%d ", get_value(array, i));

    destructor(array);

    return 0;
  }


Espero que te pueda haber ayudado en algo.

-- 
Saludos,
 Gilberto Cuba Ricardo





Más información sobre la lista de distribución Cconclase