[C con Clase] funcionamiento de calloc

Xan Bellón xaninverno en gmail.com
Mar Feb 15 15:13:58 CET 2011


Hola

Estoy realizando un programa muy sencillo para crear un cuadrado mágico, es
decir, un cuadrado que dado un número entero impar *num*, cree una matriz de
*num***num* y lo rellene con números enteros (de 1 a *num*) de modo que la
diagonal, cada fila y cada columna sumen lo mismo. La cuestión es que para
solucionar este programa creo un array de punteros para contener los
elementos de la matriz y me sucede algo muy curioso con calloc, he resaltado
el código en negrita para localizarlo mejor.

La cuestión es que para num = 5 como ejemplo, crea correctamente el array de
punteros, y crea perfectamente los 4 primeros arrays, inicializandolos a 0.

**matriz = 0x602010
*matriz[0] = 0x602030
*matriz[1] = 0x602050
*matriz[2] = 0x602070
*matriz[3] = 0x602090
*matriz[4] = 0x6020b0

En el momento que asigna a matriz[4] la dirección 0x6020b0 el elemento
matriz[0][0] pasa de 0 a 6299824. SI cambio esto a 0 con una instrucción del
tipo matriz [0][0] = 0; *matriz[4] deja de estar referenciado. Da igual que
utilice la notación de arrays (matriz[i] o la de punteros *(matriz+i) )
Existe algún vinculo a la memoria que haya pasado por alto?

Muchas gracias por la ayuda.
Xan.

Posteo el código a continuación:

void crtCuadrado (int num) // num viene de la función main, que se encarga
de comprobar que es un número impar
{

    int **matriz;               /* Puntero a array de punteros para reservar
espacio en memoria para almacenar los numeros */
    int i;                      /* Indices para bucles */
    int fil, col;               /* Indices de fila y columna */
    int tope = num*num;                   /* Será el valor máximo que pueden
tomar los números del cuadrado, es decir num*num */

*    /** Reservamos memoria para el array de punteros, cada puntero de este
array referencia cada fila de enteros **/
    matriz = (int**)malloc((num) * sizeof (int));

    /** Se reserva memoria para cada fila poniendo a 0 sus elementos, por
eso se utiliza calloc, que hace las dos cosas a la vez **/
    for (i = 0; i < num; i++)
    {
        *(matriz+i) = (int*)calloc (num, sizeof(int));
    }

    **(A partir de aquí el código funciona correctamente, salvo por el
detalle de que llega a un elemento que no está a 0 y eso hace que todo salte
por los aires)*
   * /** Se coloca el número 1 en la mitad de la primera fila **/
    fil = 0;
    col = num/2;                     //(num/2) nos da la mitad de la fila

    *(*(matriz + fil)+col) = 1;

    for (i = 2; i <= tope; i++)         /* i tomará todos los restantes
valores desde 2 hasta num^2 */
    {
        fil = fil - 1;                      // Se sube una fila
        col = col + 1;                        // Se situa una columna a la
derecha

        /** Se comprueba si fil o col se han salido del rango de la matriz
(num) y se reajustan sus valores dentro del rango **/
        if (fil < 0 || fil >= num || col < 0 || col >= num)
            chkRango (&fil, &col, num);

        if (*(*(matriz + fil) + col))       // Si ese elemento es distinto
de 0 se reajusta su posición
        {
            fil = fil + 2;                  // Nos colocamos en la posición
inferior al último elemento
            col = col - 1;

            /** Se comprueba si fil o col se han salido del rango de la
matriz (num) y se reajustan sus valores dentro del rango **/
            chkRango (&fil, &col, num);
        }

        /** Una vez comprobados y ajustados los indices se asigna el valor
al array **/

        *(*(matriz + fil) + col) = i;

    }


    /*** Asignados todos los valores, se pinta en pantalla el cuadrado
mágico ***/
    printf("\n\n");
    printf("Cuadrado magico de orden %d",num);
    printf("\n****************************\n\n");


    for (fil = 0; fil < num; fil++)
    {
        for (col = 0; col < num; col++)
        {
            printf ("%d ", matriz[fil][col]);
        }

        printf ("\n");
    }

    /*** Finalmente se vacía la memoria reservada ***/
    for (i = 0; i < num; i++)
        free (matriz[i]);

    free (matriz);
}

void chkRango (int *fil, int *col, int num)
{
    if (*fil < 0)
        *fil = num + *fil;

    if (*col < 0)
        *col = num + *col;

    if (*fil >= num)
        *fil = (*fil - num);

    if (*col >= num)
        *col = (*col - num);
}*



-- 
Una vez le preguntaron al Buda que es lo que a él más le sorprendía de la
humanidad. El Buda respondió: "Los hombres, que pierden la salud para juntar
dinero, y luego pierden el dinero para recuperarla y que por pensar
ansiosamente en el futuro olvidan el presente de tal forma, que acaban por
no vivir ni el presente ni el futuro. Viven como si nunca fuesen a morir, y
mueren como si nunca hubiesen vivido".
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20110215/497cb3dc/attachment.html>


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