Acabamos de hablar hace nada de cómo reservar memoria para un vector unidimensional de forma dinámica con C. Hoy le toca el turno a las matrices o arrays bidimensionales. Los vectores se organizan de forma lineal, secuencial y con todos los elementos en posiciones correlativas en la memoria. Las matrices se almacenan en forma de vector de vectores.
Dimensiones fijas
Si es de dimensiones fijas (declarándolas como matriz[filas][columnas]), el vector de vectores se guardará también uno al lado del otro.
Por lo tanto, en una matriz del tipo:
a00 | a01 | a02 |
a10 | a11 | a12 |
a20 | a21 | a22 |
En memoria (en la que los elementos los direccionamos en una sola dirección) los tendríamos de la siguiente forma (en cada lenguaje este criterio cambia, en Fotran se almacena en forma de vector de columnas):
a00 | a01 | a02 | a10 | a11 | a12 | a20 | a21 | a22 |
Dimensiones variables
Sin embargo, en el caso de la memoria dinámica, las cosas cambian. El mecanismo será el siguiente:
Hay dos detalles a tener en cuenta:
Veamos un ejemplo con código real (no hace comprobaciones de que el malloc se ejecute correctamente):
#include <stdlib.h> #include <stdio.h> int main(void) { int filas = 2; int columnas = 3; int **x; int i; // Recorre filas int j; // Recorre columnas // Reserva de Memoria x = (int **)malloc(filas*sizeof(int*)); for (i=0;i<filas;i++) x[i] = (int*)malloc(columnas*sizeof(int)); // Damos Valores a la Matriz x[0][0] = 1; x[0][1] = 2; x[0][2] = 3; x[1][0] = 4; x[1][1] = 5; x[1][2] = 6; // Dibujamos la Matriz en pantalla for (i=0; i<filas; i++) { printf("\n"); for (j=0; j<columnas; j++) printf("\t%d", x[i][j] ); } return 0; }
https://www.youtube.com/embed/z-xGk9c_eOw Guionista y locutor: Manuel Ignacio López Quintero.Fecha de publicación: 31 de diciembre de 2024.
Ver comentarios
En tu ejemplo, CREO, que la tabla no estaría en posiciones consecutivas. Para lograrlo, y teniendo en cuenta que las dimensiones las conocemos podríamos hacer algo así:
x[0]=(int*)malloc(filas*columnas*sizeof(int)); //reserva espacio para toda la tabla
for (i=1;i<filas;i++) //apuntar a cada fila (la 0 ya está)
x[i] = x[i-1]+columnas;
Bueno, la verdad es que no estoy muy seguro, tengo el tema un poco oxidado... Haber si alguien lo puede confirmar.
Un saludo, y a seguir disfrutando del verano. ¡Que poco queda!
@Miguel: En mi ejemplo, sólo estaría en posiciones correlativas los vectores que reservo en la iteración, pero cada vector de estos no estarían juntos.
Creo que lo que planteas no funcionaría pero no te lo sé decir a ciencia cierta. ¿Alguien puede sacarnos de dudas? Podríamos hacer el ejemplo y compilarlo... si tengo tiempo lo hago y os lo cuento.
La única manera en la que sé seguro que sí están juntos es declarándola estáticamente.
Lo que dice Miguel funciona, pero para aclararlo expongo el código a sustituir:
// Reserva de Memoria
x = (int **)malloc(filas*sizeof(int*));
for (i=0;i<filas;i++)
x[i] = (int*)malloc(columnas*sizeof(int));
Y se cambiaría por:
x = (int **)malloc(filas*sizeof(int*)); //reserva para punteros a cada fila
x[0]=(int*)malloc(filas*columnas*sizeof(int)); //reserva para datos de la tabla
for (i=1;i<filas;i++) //apuntar a cada fila (la 0 ya está)
x[i] = x[i-1]+columnas; //punt_fila_siguiente=punt_fila_anterior + columnas
Hasta la próxima...
@yomismo: Genial apunte.
Hola soy estudiante de primer año y me dejaron de tarea crear un programa en c++ con new y delate que se ocupe de reservar toda la memoria RAM, y me gustaria que alguien me de alga guia o masomenos como le haria
@Hola Una duda: En C++ tenemos el operador que se le pasa el tipo y el número de elementos a reservar.
Si tu memoria es de 1GB podrías hacer new char[1024*1024*1024], no sé si habrá un problema por representar un entero tan largo (si lo hay hazlo mediante tres bucles de 1024 por ejemplo). Ten en cuenta que 1GB son 1024MB y a su vez 1MB son 1024KB y 1KB son 1024B que casi con total seguridad son lo que ocupa un char en tu compilador/arquitectura.
Puedes hacer sizeof para asegurarte.
Lo que sí es cierto es que reservaras una cantidad de memoria equivalente a toda tu RAM pero como habrá cosas cargadas, el sistema operativo se encargará de pedir memoria virtual.
totalmente insipido el algoritmo pero me ayudo bastante y me dio mushas ideas gracias.
Como libero la RAM ? ?
Existe un método free() que es justo para eso. Se aplica sobre un puntero y en este caso deberías aplicarlo primero por cada x[i] y luego sobre x.
Cuando el proceso termina, el sistema operativo, si no has liberado la memoria, la libera él.
No todos.
Yo lo resolví de esta forma. declare una estructura (q genera un nuevo tipo de variable , q llame "matriz")que contiene un arreglo bidimensional, luego creo una variable de tipo puntero a "matriz" y con malloc obtengo un punteo al primer lugar de memoria. Para acceder a las filas y columnas lo hago como se hace comúnmente con estructuras. Les dejo el programa.
#include
#include
typedef struct
{
int mat[5][5];
}matriz;
int main(void)
{
matriz *tre=(matriz*)malloc(sizeof(matriz));
int i,j;
srand(time(NULL));
for(i=0;i<5;i++)
for(j=0;jmat[i][j]=rand()%100;
for(i=0;i<5;i++)
{
for(j=0;jmat[i][j]);
printf("n");
}
free(tre);
return 0;
}
Les dejo el link de un blog de programacion que estoy armando: http://comoseprogramaenc.blogspot.com.ar/
No te sirve de nada eso porque conoces el tamaño de antemano de las filas y columnas. La función free le pide al sistema operativo que asigne memoria disponible en tiempo de ejecución. Tu programa lo hace en la compilación, eso quiere decir que siempre ocupará la misma memoria. En este programa que subió el amigo el tamaño de filas y columnas puede varias en tiempo de ejecución y no desbordará la memoria como el código que hiciste si lo intentas hacer en tiempo de ejecución.
Y el free?
Haría falta al final, gracias por el apunte.