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;
}