[C con Clase] Problemas y dudas varias con punteros.

Steven Davidson srd4121 en njit.edu
Jue Abr 30 21:03:56 CEST 2009


Hola Kalith,

Kalith wrote:
> Ok sigo luchando con punteros tengo una pequeña duda..
> 
> tengo el siguiente source:
> 
> #include <iostream>
> 
> using namespace std;
> 
> int main(void)
> {
>     int *pInt;
> 
>     for(int i = 0; i < 10; i++)
>     {
>         pInt = new int[i + 1];
>         *pInt = i*2;
>         cout << *pInt++ << endl;
> 
> 
>     }
> }
> 

Este código tiene varios errores. En primer lugar, estás creando 
diferentes arrays dinámicos en cada iteración y asignando su dirección 
de memoria a 'pInt'. Sin embargo, no liberas la memoria y por tanto se 
pierde la dirección a los bloques de memoria que creaste. Esto significa 
que no hay forma de liberar tales bloques, perdiendo memoria.

El segundo error es que luego incrementas póstumamente el puntero, por 
lo que no apuntará al comienzo del bloque de memoria. Esto también 
implica que pierdes el "enlace" a la dirección de la memoria del array 
dinámico. Es cierto que esto sería al final del bucle y por consiguiente 
no existe un grave error porque no se vuelve a usar 'pInt'.

Por último, debes retornar un número entero para 'main()'. Por convenio, 
se retorna 0 (cero) para indicar que el programa ha terminado exitosamente.

> me arroja como salida
> 
> 0
> 2
> 4
> 6
> 8
> 10
> 12
> 14
> 16
> 18
> 
> ok todo perfecto, ahora hago esto:
> 
> #include <iostream>
> 
> using namespace std;
> 
> int main(void)
> {
>     int *pInt;
> 
>     for(int i = 0; i < 10; i++)
>     {
>         pInt = new int[i + 1];
>         *pInt++ = i*2;
>     }
> 

Tienes los mismos problemas que en el caso anterior.

>     cout << pInt[1] << endl;
> }
> 
> el 1 es cualquier constante en donde intento siempre arroja 0..
> 

Esto es porque no has asignado ningún valor válido para 'pInt[1]' el 
cual accede al segundo elemento. Por lo tanto, estás mostrando "basura".

> ok otra cosa el dilema retornar un puntero pero de la siguiente forma
> 
> imaginen que tengo este caso
> 
> char arreglo[] = funcion(int parametro)
> 
> ok pero que quiero hacer pues que haga una serie de operaciones con
> un arreglo que solo se crea dentro de la funcion y lo pueda asigar al
> arreglo, el problema si creo el arreglo dentro de la funcion
> apuntaria lo que retorne a un sector de memoria que cuando salga de
> la funcion va a morir entonces no se puede.. y la idea es no pasar
> por referencia el arreglo que quiero llenar
> 

Si no quieres pasar el array para ser operada y modificada por la 
función, entonces tienes que usar punteros. Por ejemplo,

int *crearLista10()
{
   int *p = new int[10];
   for( int i=0; i<10; i++ )  *p++ = i;

   return p-10;
}

int main()
{
   int *pLista = crearLista10();
   ...
   delete[] pLista;
   return 0;
}

Hemos creado memoria dinámicamente y luego hemos rellenado los 10 
elementos de tal bloque de memoria en la función 'crearLista10()'. 
Ciertamente, la variable local 'p' se destruye al terminar de ejecutar 
esta función, pero el valor contenido es retornado al punto de llamada. 
En el ejemplo anterior, esto significa que la dirección de memoria del 
bloque creado dinámicamente sirve para inicializar el puntero 'pLista' 
en 'main()'.

Ten presente que un puntero sigue siendo una variable y por tanto las 
operaciones básicas de punteros se aplican a los punteros; 
concretamente, la operación de acceso tanto para lectura como para 
escritura.


Dicho todo esto, arreglamos tu ejemplo de esta forma:

#include <iostream>

using namespace std;

int main()
{
   int *pInt;

   for( int i=0; i < 10; i++ )
   {
     pInt = new int[i+1];
     *pInt = i*2;
     cout << *pInt++ << endl;

     delete[] pInt-1;
   }

   return 0;
}


Espero que esto aclare las dudas.

Steven





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