Administración de memoria - arreglos estáticos y dinámicos

30
Administración de memoria Uso intensivo de memoria

description

Introducción al manejo de memoria dinámica, con un ejemplo de arreglos dinámicos en C++.

Transcript of Administración de memoria - arreglos estáticos y dinámicos

Page 1: Administración de memoria - arreglos estáticos y dinámicos

Administración de memoria

Uso intensivo de memoria

Page 2: Administración de memoria - arreglos estáticos y dinámicos

¿Qué es la memoria?

• Es un lugar donde se guarda información a usar.

• Cuando declaramos una variable o un arreglo, el programa indica que se debe reservar un espacio de memoria (la cantidad depende del tipo de dato) desde antes de compilar

• Esta memoria permanecerá apartada para ser usada durante el tiempo que el programa lo requiera

Page 3: Administración de memoria - arreglos estáticos y dinámicos

Recordamos la estructura de un micro procesador

Page 4: Administración de memoria - arreglos estáticos y dinámicos
Page 6: Administración de memoria - arreglos estáticos y dinámicos
Page 7: Administración de memoria - arreglos estáticos y dinámicos

Para ilustrar la administración de memoria…

• Usemos un ejemplo en donde tengamos que usar mucha memoria.

Page 9: Administración de memoria - arreglos estáticos y dinámicos

• Sabemos que podemos hacer un arreglo tan grande como queramos.

• ¿Recuerdas cómo crear, llenar y mostrar un arreglo en C++?

• Hagamos un ejemplo en Visual Studio…

Page 10: Administración de memoria - arreglos estáticos y dinámicos

Si lo hiciéramos como procedimiento definido por el usuario…

void arregloEstatico(void){

int aE[TAM]; //aquí se declara el arreglo estático cuyo tamaño fijo //está definido por la constante TAM

cout << "\nARREGLO ESTATICO\n";

//ciclo para llenar el arreglo estático for (int i = 0; i < TAM; i++){ cout << "\nEscribe elemento " << i << " del arreglo: "; cin >> aE[i]; } cout << "\n";//imprime en pantalla una línea en blanco

//ciclo para mostrar arreglo estático for (int i = 0; i < TAM; i++) cout << aE[i] << " ";

cout << "\n";//imprime en pantalla una línea en blanco}//fin procedimiento arregloEstatico

Page 11: Administración de memoria - arreglos estáticos y dinámicos

Pero …

• ¿Qué pasa si queremos cambiar el tamaño del arreglo durante ejecución?

• C++ permite cambiar la memoria según se va necesitando

• A esto se llama “memoria dinámica”• Las ventajas de la memoria dinámica es que se

aprovecha mejor la memoria de la máquina, apartando solamente lo que se necesita

Page 12: Administración de memoria - arreglos estáticos y dinámicos

Operadores “new” y “delete”

• new() permite reservar memoria de almacén libre

• delete() permite librear la memoria cuando ya no se necesita

Page 13: Administración de memoria - arreglos estáticos y dinámicos

NEW

• Permite reservar un bloque de memoria y devuelve la dirección de comienzo de dicho bloque

<variable_apuntador> = new <tipo_dato>;

char *p = NULL;p= new char;

Page 14: Administración de memoria - arreglos estáticos y dinámicos

NEW

• Con este operador también se pueden reservar bloques de memoria para arreglos.

• Estos se conocen como arreglos dinámicos.• Si el operador “new” falla, devuelve un nulo,

por lo que es obligatorio comprobar que el compilador ha podido realizar la reserva de memoria.

Page 15: Administración de memoria - arreglos estáticos y dinámicos

Ejemplo práctico

• Ahora realicemos un arreglo dinámico en C++ usando Visual Studio…

Page 16: Administración de memoria - arreglos estáticos y dinámicos

• Si lo escribiéramos como un procedimiento definido por el usuario, quedaría…

Page 17: Administración de memoria - arreglos estáticos y dinámicos

void arregloDinamico(void){int tamDin = 0; //variable para que el usuario indique el tamaño del arreglo que quiere

cout << "\nARREGLO DINAMICO\n";cout << "Escribe el tamaño del arreglo de enteros: ";//pide a usuario tamaño deseadocin >> tamDin; //se guarda el tamaño en variable tamDin

int *pArregloDin; //apuntador para guardar dirección de inicio del arreglo dinámicopArregloDin = new int[tamDin]; //se aparta memoria dinámica para el arreglo pArregloDin

//ciclo para llenar los elementos del arreglo dinámico for (int i = 0; i < tamDin; i++){cout << "\nElemento " << i << " ";//pide al usuario ingrese cada uno de //los elementos del arreglocin >> pArregloDin[i];}//fin forcout << "\n";//imprime en pantalla una línea en blanco

//ciclo para mostrar arreglo dinámicofor (int i = 0; i < tamDin; i++)cout << pArregloDin[i] << " "; //fin forcout << "\n";//imprime en pantalla una línea en blanco

delete pArregloDin; //librea la memoria dinámica reservada para el arreglo}//fin procedimiento arreglo dinámico

Page 18: Administración de memoria - arreglos estáticos y dinámicos

La estructura de un programa que use ambos procedimientos mostrados es:#include <iostream>

using namespace std;

#define TAM 10

void arregloEstatico(void);void arregloDinamico(void);

int main(){ //arreglo estático arregloEstatico();

//arreglo dinámico arregloDinamico();

system("pause"); return 0;}//fin main

Recuerda que , después de la

función “main” se escriben

las definiciones de los

procedimientos

“arregloEstatico” y

“arregloDinamico”

Page 19: Administración de memoria - arreglos estáticos y dinámicos

Errores de memoria

Page 20: Administración de memoria - arreglos estáticos y dinámicos

• La corrupción de memoria ocurre en un programa cuando los contenidos de una dirección de memoria se modifican involuntariamente debido a errores de programación.

Page 21: Administración de memoria - arreglos estáticos y dinámicos

• Cuando los contenidos corruptos de memoria se usan más adelante en el programa, llevan a un error o comportamiento extraño del mismo.

Page 22: Administración de memoria - arreglos estáticos y dinámicos

• La utilización de apuntadores que dan acceso explícito a direcciones de memoria y aritmética de apuntadores, que permiten desarrollar aplicaciones eficientes, si no se usan de forma adecuada pueden ocasionar errores de corrupción de memoria.

Page 23: Administración de memoria - arreglos estáticos y dinámicos

• Estos errores son los más peligrosos y los más difíciles de detectar debido a:– El origen de la corrupción de memoria y su

manifestación durante la ejecución del programa, pueden estar muy separados, por lo que es difícil relacionar la causa y el efecto.

– Los “síntomas” aparecen en condiciones inusuales, por lo que es difícil reproducir el error de manera consistente o constante.

Page 24: Administración de memoria - arreglos estáticos y dinámicos

Categorías de errores

1. Utilización de memoria no inicializada: se considera que los contenidos de la memoria no inicializada son valores basura (como poner comida recién hecha en un plato sucio), y usar estos valores puede llevar al comportamiento imprevisible del programa.

Page 25: Administración de memoria - arreglos estáticos y dinámicos

Categorías de errores (cont.)

2. Uso de memoria sin dueño: Cuando un apuntador es nulo o apunta a una sección de memoria ya liberada, o una ubicación de memoria que esta fuera de la pila de memoria del programa. Suelen causar excepciones de “fallos de página”, lo que lleva a una falla del programa.

Page 26: Administración de memoria - arreglos estáticos y dinámicos

Categorías de errores (cont.)

3. Usar memoria más allá de la asignada (buffer overflow): Si se tiene un arreglo que es usado dentro de un bucle/ciclo que tiene sus contadores de elementos incorrectos, la memoria más allá de los límites del arreglo puede ser manipulada.

Page 27: Administración de memoria - arreglos estáticos y dinámicos

Categorías de errores (cont.)

4. Gestión defectuosa de memoria heap: Fugas de memoria y liberar memora que no es del “heap” o está sin asignar.

Page 28: Administración de memoria - arreglos estáticos y dinámicos

Cómo evitar fugas de memoria

• Una fuga de memoria es un error de programación que ocurre cuando un programa no libera toda la memoria que se reservó, y debido a esto la aplicación puede quedarse sin memoria y causar que el sistema falle.

• Para prevenir esto se debe saber cuándo ocurren y hacer buen uso de los operadores “new” y “delete”.

Page 29: Administración de memoria - arreglos estáticos y dinámicos

Cómo evitar fugas de memoria

1. Por cada “new” se debe utilizar un “delete” para liberar la misma cantidad de memoria reservada con “new”.

2. Reserva memoria sólo si la has borrado.char * str = new char[30]; //aparta dirección mem//delete [] str; //esta linea corrige errorstr = new char [60]; //da otra dirección de mem//se pierde la primera memoria apartada

3. Vigila las asignaciones de apuntadores.

Page 30: Administración de memoria - arreglos estáticos y dinámicos

Tarea MRR

• Investiga qué es el “heap” de memoria y escríbelo en tu cuaderno MRR

• Investiga códigos en C++ que ejemplifiquen los tipos de errores de manejo de memoria mencionados aquí.

• Describe cada ejemplo que investigaste, detallándolo por escrito en tu cuaderno MRR.