[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