Memoria dinámica
Estructura de archivos:
📁 07_Memoria
└── 📁 Memoria-NN
├── 📄 main.c
└── 📄 Makefile
Ejercicios:
Memoria dinámica 01
Makefile
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic
PROG = main
OBJ = main.o
$(PROG): $(OBJ)
$(CC) $(OBJ) -o $(PROG)
$(OBJ): main.c
$(CC) $(CFLAGS) -c main.c
.PHONY: clean
clean:
del $(OBJ) $(PROG).exe
Código:
// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main
/* Comando de compilacion:
* - -std=c11 => utiliza el estandar C11.
* - -Wall => activa advertencias comunes.
* - -Wextra => activa advertencias adicionales.
* - -pedantic => exige cumplimiento estricto del estandar.
* - -0 main => genera el ejecutable llamado 'main'.
*/
#include <stdlib.h> // Se usa malloc(), free(), exit(), system()
#include <stdio.h> // Se usa printf(), scanf()
#include <conio.h> // Se usa getch()
int main(void)
{
/* Declaracion de puntero a int */
int *p;
system("cls"); /* Limpia la pantalla en Windows en Linux "clear" */
/* Reserva memoria dinamica para un entero */
p = malloc(sizeof(int));
/* Verifica si malloc fallo (No hay memoria disponible) */
if (!p)
{
printf("\nNo hay memoria suficiente");
printf("\nPresione una tecla para continuar");
getch(); /* Espera que se presione una tecla */
exit(1); /* Finaliza inmediatamente el programa */
}
else
{
/* Muestra el contenido de la memoria recien reservada */
printf("\n\nEl valor existente en la direccion %p es %d", p, *p); // %p espera un puntero a void (void *), cambiar p a (void *)p
/* Pide al usuario que ingrese un valor entero */
printf("\nIngrese un valor entero ");
/* Guarda el valor ingresado directamente en la direccion apuntada por p */
scanf("%d", p);
}
/* Muestra el valor que el usuario ingreso */
printf("\n\nEl valor ingresado en la direccion %p es %d", p, *p); // %p espera un puntero a void (void *), cambiar p a (void *)p
/* Libera la memoria reservada */
free(p);
return 0;
}
Memoria dinámica 02
Makefile
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic
PROG = main
OBJ = main.o
$(PROG): $(OBJ)
$(CC) $(OBJ) -o $(PROG)
$(OBJ): main.c
$(CC) $(CFLAGS) -c main.c
.PHONY: clean
clean:
del $(OBJ) $(PROG).exe
Código:
// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main
#include <stdio.h> // Se usa printf(), scanf()
#include <stdlib.h> // Se usa malloc(), free(), exit(), system(), getchar()
int main(void)
{
/* Declaracion de puntero a int */
int *p;
system("cls"); /* Limpia la pantalla en Windows en Linux "clear" */
/* Reserva memoria dinamica para un entero y verifica si fallo */
if (!(p = malloc(sizeof(int))))
{
printf("\nNo hay memoria suficiente");
printf("\nPresione una tecla para continuar");
getchar(); /* Espera entrada del usuario */
exit(1); /* Finaliza inmediatamente el programa */
}
/* Muestra el valor que hay en la memoria recien reservada */
printf("\n\nEl valor existente en la direccion %p es %d", (void *)p, *p); // %p espera un puntero a void (void *), cambiar p a (void *)p
/* Solicita al usuario quue ingrese un numero entero */
printf("\nIngrese un valor entero ");
/* Guarda el valor ingresado directamente en la direccion apuntada por p */
scanf("%d", p);
/* Muestra el valor que el usuario ingreso */
printf("\n\nEl valor existente en la direccion %p es %d", (void *)p, *p); // %p espera un puntero a void (void *), cambiar p a (void *)p
/* Libera la memoria reservada */
free(p);
/* ERROR logico:
* Se esta accediendo a memoria ya liberada (dangling pointer)
* Esto produce comportamiento indefinido (UB)
*/
printf("\n\nEl valor existente en la direccion %p es %d", (void *)p, *p);
return 0;
}
Memoria dinámica 03
Makefile
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic
PROG = main
OBJ = main.o
$(PROG): $(OBJ)
$(CC) $(OBJ) -o $(PROG)
$(OBJ): main.c
$(CC) $(CFLAGS) -c main.c
.PHONY: clean
clean:
del $(OBJ) $(PROG).exe
Código:
// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main
#include <stdio.h>
#include <stdlib.h> // Se usa malloc(), system()
int main(void)
{
/* Declaracion puntero a char */
char *p;
/* Declaracion variable de tipo long int para acumular la cantidad de memoria reservada */
long l;
system("cls"); /* Limpia la pantalla en Windows en Linux "clear" */
/* Inicializacion del contador de memoria en cero */
l = 0;
/* Bucle que intenta reservar memoria repetidamente */
do
{
/* Intenta reservar 100000 bytes (aprox. 100 KB) */
p = malloc(100000);
/* Si la reserva fue exitosa (p != NULL) */
if (p)
l += 100000; /* Suma el total de memoria */
}
while (p); /* Continua hasta que malloc falle (devuelva NULL) */
/* Muestra cuanta memoria se pudo reservar en total*/
printf("tiene %ld bytes de memoria\n", l);
return 0;
}
Memoria dinámica 04
Makefile
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic
PROG = main
OBJ = main.o
$(PROG): $(OBJ)
$(CC) $(OBJ) -o $(PROG)
$(OBJ): main.c
$(CC) $(CFLAGS) -c main.c
.PHONY: clean
clean:
del $(OBJ) $(PROG).exe
Código:
// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main
#include <stdio.h>
#include <stdlib.h> // Se usa malloc(), system()
int main(void)
{
system("cls"); /* Limpia la pantalla en Windows en Linux "clear" */
/* Muestra la dimension en bytes de distintos tipos de datos
* sizeof devuelve la cantidad de memoria que ocupa cada tipo
*/
printf("char %d\nint %d\nfloat %d", sizeof(char), sizeof(int), sizeof(float)); // sizeof devuelve long long unsigned int usar el especificado %zu en lugar de %d
/* Reserva memoria para un char y muestra la direccion asignada
* malloc devuelve un puntero a la memoria reservada
*/
printf("\n%p", malloc(sizeof(char)));
/* Reserva memoria para un int y muestra la direccion */
printf("\n%p", malloc(sizeof(int)));
/* Reserva memoria para un flot y muestra la direccion */
printf("\n%p", malloc(sizeof(float)));
return 0;
}
Memoria dinámica 05
Makefile
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic
PROG = main
OBJ = main.o
$(PROG): $(OBJ)
$(CC) $(OBJ) -o $(PROG)
$(OBJ): main.c
$(CC) $(CFLAGS) -c main.c
.PHONY: clean
clean:
del $(OBJ) $(PROG).exe
Código:
// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main
#include <stdio.h>
#include <stdlib.h> // Se usa system()
int main(void)
{
/* Declaracion de variables
* Entero, char, vector de 15 elementos de tipo char
* Numero real
* Entero no signado
* Char no signado
* Entero largo
* Entero largo no signado
* Numero real (doble presicion)
* Vector de 20 elementos de tipo int
* */
int a;
char b, o[15];
float c;
unsigned int d;
unsigned char e;
long f;
unsigned long g;
double h;
int i[20];
/* Declaracion de estructura */
struct l
{
char c, d, e;
}j, k[10];
/* Declaracion de union */
union m
{
struct l a, b;
char c[19];
}n;
system("cls"); /* Limpia la pantalla en Windows en Linux "clear" */
/* Muestra la dimension en bytes de cada variable
* sizeof devuelve long long unsigned int usar el especificado %zu en lugar de %d
*/
printf("La dimension de a es:%d\n", sizeof(a));
printf("La dimension de b es:%d\n", sizeof(b));
printf("La dimension de c es:%d\n", sizeof(c));
printf("La dimension de d es:%d\n", sizeof(d));
printf("La dimension de e es:%d\n", sizeof(e));
printf("La dimension de f es:%d\n", sizeof(f));
printf("La dimension de g es:%d\n", sizeof(g));
printf("La dimension de h es:%d\n", sizeof(h));
/* Muestra la dimension de los tipos de datos */
printf("La dimension del int es:%d\n", sizeof(int));
printf("La dimension del char es:%d\n", sizeof(char));
/* Muestra la dimension de un vector completo */
printf("La dimension de i es:%d\n", sizeof(i));
/* Muestra la dimension de la estructura */
printf("La dimension de j es:%d\n", sizeof(j));
/* Muestra la dimension del vector de estructuras de 10 elementos */
printf("La dimension de k es:%d\n", sizeof(k));
/* Muestra la dimension del tipo de dato struct l */
printf("La dimension de struct l es:%d\n", sizeof(struct l));
/* Muestra la dimension del cuarto elemento del vector k */
printf("La dimension de k es:%d\n", sizeof(k[4]));
/* Muestra la dimension de la union (Depende del miembro mas grande) */
printf("La dimension de n es:%d\n", sizeof(n));
printf("La dimension de m es:%d\n", sizeof(union m));
/* Muestra la dimension del vector de chars */
printf("La dimension de o es:%d\n", sizeof(o));
return 0;
}