Error de printeo con puntero triple

Iniciado por Locura_23, 21 Agosto 2021, 21:33 PM

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

Locura_23

Hola genios. Bueno resulta que estoy practicando el manejo de punteros y arreglos, pero estoy teniendo problemas: no se muestran los valores desde main. Alguien puede notar algo? Si nadie se quiere molestar lo entiendo porque puede parecer complejo... gracias saludos.


//la funcion crearArreglo maneja la creacion del arreglo, primero guarda
//la memoria necesaria y luego le copia los valores.
//crearArreglo recibe un puntero a entero y la dimension.
//Luego le pasa el puntero a puntero
//a otra funcion asignarMemoria. Luego le pasa el puntero a puntero
//a copiarValores, donde se asignan numeros random.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void crearArreglo(int**punteroApuntero, int dim);
void asignarMemoria(int***punteroTriple, int dim );
void copiarValores(int ***punteroTriple, int dim);

int main()
{
   int *pArreglo = NULL;
   int dim = 0; //dimension

   printf("\nIngrese la dimension del arreglo: ");
   scanf("%d",&dim);

   srand(time(NULL)); //para obtener valores random en copiarValores()
   crearArreglo(&pArreglo,dim); //se le pasa el puntero a puntero y la dimension

   printf("\nPrimer elemento desde main: %d\n",*pArreglo); //printea un valor erroneo

   return 0;

}// fin main

void crearArreglo(int **punteroApuntero, int dim)
{
   asignarMemoria(&punteroApuntero, dim);

   copiarValores(&punteroApuntero, dim);

}// fin funcion crearArreglo

void asignarMemoria(int ***punteroTriple, int dim)
{
   (**punteroTriple) = (int *) malloc ( dim * sizeof(int) );

   if( (**punteroTriple) == NULL )
   {
       printf("\nError en asignacion de memoria.\n");
       exit(EXIT_FAILURE);
   }//fin if
   else
   {
       printf("\nAsignacion de memoria exitosa.\n");

   } // fin else

} // fin funcion asignarMemoria

void copiarValores(int ***punteroTriple, int dim)
{
   int i = 0;

   while( i < dim )
   {
       (***punteroTriple) = rand() % 10;
       printf("Elemento %d : %d\n",i,***punteroTriple);
       system("pause");
       (**punteroTriple)++; //dudas aca
       i++;
   }// fin while

} // fin funcion copiarValores

MAFUS

No tiene sentido usar puntero triple. Lo que te importa es la dirección de memoria que contendrá pArreglo y cambiarlo en otra función. Como sabes un argumento de una función es una copia de un dato y para modificar el valor de una variable se pasa el puntero a esa variable (así el puntero es la copia y lo que hay dentro se modifica), por eso se pasa un puntero a puntero.

Como crearArreglo va a crear un array dinámico que debe ser devuelto (a a introducir en pArreglo un valor), esta función debe recibir la dirección de pArreglo (que es copia, pero su dato sí se puede modificar).

Ídem para asignarMemoria. No debe ser un puntero triple porque es realmente la encargada de crear el array e introducir esa dirección de memoria en pArreglo. La dirección de pArreglo ya la has pasado en el argumento punteroApuntero de crearArreglo y es lo que te interesa, así que se lo das sin más.

Totalmente diferente es el trabajo en copiarValores. Allí sólo te interesa rellenar el array, no debes modificar su dirección de memoria y por tanto debes pasarle la dirección del propio array. Vas a modificar su contenido.

Sería algo así:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void crearArreglo(int **punteroApuntero, int dim);
void asignarMemoria(int **punteroApuntero, int dim );
void copiarValores(int *puntero, int dim);

int main()
{
    int *pArreglo = NULL;
    int dim = 0; //dimension

    printf("\nIngrese la dimension del arreglo: ");
    scanf("%d",&dim);

    srand(time(NULL)); //para obtener valores random en copiarValores()
    crearArreglo(&pArreglo,dim); //se le pasa el puntero a puntero y la dimension

    printf("\nPrimer elemento desde main: %d\n",*pArreglo);

    free(pArreglo); // recuerda que siempre que adquieres memorias a mano debes liberarla a mano.

    return 0;

}// fin main

void crearArreglo(int **punteroApuntero, int dim)
{
    asignarMemoria(punteroApuntero, dim);

    copiarValores(*punteroApuntero, dim);

}// fin funcion crearArreglo

void asignarMemoria(int **punteroApuntero, int dim)
{
    (*punteroApuntero) = (int *) malloc ( dim * sizeof(int) );

    if( (*punteroApuntero) == NULL )
    {
        printf("\nError en asignacion de memoria.\n");
        exit(EXIT_FAILURE);
    }//fin if
    else
    {
        printf("\nAsignacion de memoria exitosa.\n");

    } // fin else

} // fin funcion asignarMemoria

void copiarValores(int *puntero, int dim)
{
    for(int i=0; i<dim; ++i)
    {
        puntero[i] = rand() % 10;
        printf("Elemento %d : %d\n",i,puntero[i]);
        system("pause");
    }// te lo cambio por un for. Es más conciso en este caso

} // fin funcion copiarValores

Locura_23

Ohh ya veo, con que era eso... Osea en asignarMemoria estaba ampliando el bloque de memoria del puntero al puntero de pArreglo. En vez de ampliar el bloque de memoria del puntero a la direccion de pArreglo. Y luego con ese error, en copiarValores asignaba valores en la memoria reservada en el lugar erroneo.
En resumen no estaba guardando nada en pArreglo sino en otra direccion de memoria... Por eso me mostraba siempre cero en main, pues mostraba el equivalente a NULL...

En verdad me ayudaste mucho, muchas gracias por tu tiempo Mafus