30
Estructuras de datos (Prof. Edgardo A. Franco) 1 M. en C. Edgardo Adrián Franco Martínez http://www.eafranco.com [email protected] @edfrancom edgardoadrianfrancom Repaso 02: Apuntadores y manejo de memoria dinámica Solicitado: Ejercicios 02: Programación con memoria dinámica

Repaso 02: Apuntadores y manejo de memoria dinámica · 2018-02-01 · Manejo de memoria dinámica •Una variable global, del programa principal o de una función comparte una característica

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Estructuras de datos (Prof. Edgardo A. Franco)

1M. en C. Edgardo Adrián Franco Martínez http://[email protected]

@edfrancom edgardoadrianfrancom

Repaso 02: Apuntadores y manejo de memoria dinámica

Solicitado: Ejercicios 02: Programación con memoria dinámica

Contenido• Memoria de un proceso

• Apuntadores

• Dirección de memoria

• Definición de apuntador

• Manejo de memoria dinámica

• Sentencia malloc()

• Sentencia free()

• Problema

• Solución en C

• Ejercicio 02: Programación con memoria dinámica2

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Memoria de un proceso• Durante la ejecución del proceso, todos los datos

manipulados (incluido el propio código del programacompilado) se alojan en la memoria principal, ya que estaofrece menor latencia (menor tiempo de comunicación conel CPU) respecto de los medios secundarios.

3

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

4

• Empezando por la direcciones más bajas, el segmento decódigo es la porción de la memoria donde se carga elprograma que se ejecuta.

• El segmento de datos alberga las declaraciones globales(e.g. variables del programa principal y constantesglobales).

• El montículo es la región de memoria que se toma y selibera de manera dinámica durante la ejecución delprograma.

• La pila es donde se "apilan" porciones de memoriapertenecientes a funciones y/o procedimientos cuandose les llama.

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Código

Datos

Pila

Memoria de proceso activo

Pila(Stack)

Montículo (Heap)

5

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

6

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Direcciones más bajas 0x0000AAH

0xFFFFFFH

Apuntadores• Los apuntadores o punteros son otro tipos de dato

que se utilizan en lenguaje de programación como C.

• Permiten el acceso a memoria (memoria delproceso) de manera más eficiente, sin embargo, unamala referencia a dicha memoria provocará en elprograma una salida inesperada.

7

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

8

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

• Trabajar con apuntadores implica la nomanipulación de variables en sí, sino manejardirecciones de memoria en la cuales residen losdatos.

• Una variable apuntador o puntero, es una variableque contiene direcciones de otras variables oinstrucciones, es decir, almacenan la dirección dememoria donde se encuentran los datos asociadosa dichas variables o instrucciones.

Dirección de memoria• Cuando una variable se declara, se le asocian tres

atributos fundamentales a dichas variables: suidentificador, su tipo de dato y su dirección dememoria.

por ejemplo:

int n;0x4fffd34

1234n

int

dirección de memoria

valor de la variable

tipo de dato

identificador9

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Definición de apuntador

10

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

• Cuando se declara una variable de tipo apuntador,el compilador también le asigna una dirección dememoria, sin embargo, en esa localidad dememoria no se almacena un tipo de dato simple,sino la dirección de una variable del mismo tipo quese declaro el apuntador, es decir:

int variable = 30;

int *ptr = &variable;

• Los apuntadores en C se rigen por la siguientes reglasbásicas:

1. Un apuntador es una variable como cualquier otra;

2. Una variable apuntador contiene una dirección queapunta a otra posición de memoria;

3. En esa posición de memoria se almacenan los datos a losque apunta el apuntador;

4. Un apuntador apunta a una variable que se encuentraalmacenada en alguna parte de la memoria delprograma, pudiendo ser esta una variable que apunte aotra localidad de memoria. (Dobles apuntadores, …)

5. Un apuntador común de C debe almacenar direccionesvalidas para el programa si se realiza una operación dedirección (*) sobre este, se puede causar un error deprograma al intentar acceder a direcciones invalidas parael programa.

Estructuras de datos (Prof. Edgardo A. Franco)

11

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Manejo de memoria dinámica• Una variable global, del programa principal o de una función

comparte una característica en común, se definen cuando secompila el programa. Esto significa que el compilador indicael espacio en memoria de datos y/o pila para almacenar losvalores para estas variables.

• Sin embargo, no todas las veces es posible conocer elnumero de variables con el que va a constar nuestroprograma. C ofrece al desarrollador la opción de creardiferentes tipos de variables de forma dinámica, para creartales variables se utilizan funciones como: malloc(),

realloc(), calloc(), y free(). Las memoria de trabajo deestas funciones son almacenadas en el montículo o heap. 12

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

13

• Cuando se declara una variable global o principal enC, el compilador establece un área de memoria dedatos para almacenar el contenido de la variable,cuando se hacer referencia a dicha variable, elprograma accede automáticamente a la direcciónde memoria donde se almacena el contenido lavariable para poder utilizarla.

• Si la variable es local de una función, el compiladoragrega las instrucciones necesarias para que elprograma al ingresar a la función coloque dichasvariables en la región de la pila de su memoriaasignada para acceder a ellas.

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

14

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Función malloc()• malloc() es la forma más habitual de obtener

bloques de memoria dinámica. La función genera oasigna un bloque de memoria que es el numero debytes pasados como argumento.

• malloc() devuelve un apuntador void* al bloquede memoria asignado, por lo tanto, hay que realizarun cast al tipo de apuntador requerido, para hacerbuen uso de la memoria o de los datos que selleguen a almacenar en dicho bloque de memoria.

*Nota: Todas las funciones de asignación dinámica de memoria seencuentran definidas en la biblioteca stdlib.h

15

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

• La forma de utilizar la función malloc() es:

apuntador = (tipo *)malloc(tamanio en bytes);

donde:

• apuntador: es el apuntador que almacenará lareferencia o apuntara al bloque de memoriagenerado.

• tipo *: es el cast a un apuntador valido para manejarlos datos que se van a almacenar en el bloque dememoria asignado.

• tamanio: es el tamaño en bytes del bloque de memoriaque se va a reservar.

16

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

• Al llamar a malloc() puede ser que no hayasuficiente memoria disponible, entonces,malloc() devolverá NULL en la operación, por lotanto, siempre es conveniente preguntar despuésde la operación si se asigno el bloque de memoria.

int *ptr;

ptr = (int *)malloc( 10 * sizeof(int) );

if( ptr == NULL){

printf( "No hay memoria disponible…\n" ); //no utilizar ptr

return; //fin del programa o realizar la acción conveniente

}

17

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Función sizeof() y malloc()• La función sizeof se utiliza con mucha frecuencia para

referirnos al tamaño de memoria que se va a generar por lasfunciones de memoria dinámica. Por ejemplo, si se requierereservar un bloque de memoria para un arreglo de 10enteros:

int *ptr;

ptr = (int *)malloc( 10 * sizeof(int) );

18

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Uso de malloc()para generar un arreglo bidimensional

•Un arreglo bidimensional en realidad es unarreglo cuyos elementos son arreglos. Si elnombre de un apuntador unidimensionales un apuntador sencillo, entonces, elnombre de un arreglo bidimensional seráun apuntador a apuntadores sencillos.Para asignar memoria a un arreglomultidimensional, se indica cadadimensión del arreglo al igual que sedeclara un arreglo unidimensional.

19

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

• Para generar al arreglo bidimensionalutilizando memoria dinámica se hace endos pasos:

1. Se solicita la memoria para crear unarreglo de apuntadores que van a apuntara cada fila del arreglo.int **arr2d = (int *)malloc( num_filas* sizeof(int *) );

2. Se solicita memoria para almacenar elnumero de elementos que va a formarcada fila o arreglo unidimensional(columnas).

arr2d[i] = (int*)malloc( columnas * sizeof( int ) );

20

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

arr2d

arr2d[0]

arr2d[1]

arr2d[2]

arr2d[3]

arr2d[4]

arr2d[5]

arr2d[6]

arr2d[7]

arr2d[8]

arr2d[9]

Donde cada arr2d[i] es un apuntador sencillo que apunta a un arreglo unidimensional de tamaño n.

Arreglosunidimensionales de tamaño n

Arreglo de apuntadores sencillos

21

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ezApuntador doble

Uso de free()para liberar la memoria asignada dinámicamente

• Cuando se termina de utilizar un bloque de memoriapreviamente asignado por cualquier función deasignación dinámica de memoria, se debe liberar elespacio de memoria y dejarlo disponible para otrosprocesos, esto se realiza utilizando la función free().El prototipo la función free es:

void free(void *ptr);

• Donde: *ptr es el apuntador que hace referencia albloque de memoria asignado, si ptr es NULL entoncesfree no hace nada.

• Si embargo, si ptr es un apuntador mal referenciado, eluso de free probablemente destruya el mecanismo degestión de memoria y provocará un fallo del programa.

22

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema

• Escribir una programa en C que reciba (por la entradaestándar) los valores de m (filas) y n (columnas) y genere unamatriz dinámica de enteros, posteriormente la matriz serállenada por el usuario (entrada estándar) y se llamará aintercambia_filas() que intercambiará la fila i-esima por la j-esima (i y j se introducen por la entrada estándar), finalmenteel programa mostrara la matriz resultante llamando aimprime_matriz().

23

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema(Declaración de funciones)

//DECLARACIÓN DE FUNCIONES

//Aparta el espacio de memoria para la matriz dinámica

int **Aparta_Matriz(int m,int n);

//Capturar la matriz dinámica

void Capturar_Matriz(int **matriz,int m,int n);

//Intercambia la fila i-esima por la j-esima de la matriz

void Intercambia_Filas(int **matriz,int i,int j);

//Imprime la matriz dinámica

void Imprime_Matriz(int **matriz,int m,int n);

24

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema(Programa principal)

//PROGRAMA PRINCIPAL

int main(void)

{

int m,n,**matriz;

int i,j;

//Leer m y n

printf("\nIntroduce m y n separados por espacio o enter: ");

scanf("%d %d",&m,&n);

//Apartar espacio para la matriz

matriz=Aparta_Matriz(m,n);

//Llenar la matriz de datos

Capturar_Matriz(matriz,m,n);

//Mostrar la matriz

printf("\n***Matriz Original***");

Imprime_Matriz(matriz,m,n);

//Leer i y j (Filas a intercambiar)

printf("\nIntroduce las filas i y j a intercambiar separados por espacio o

enter: ");

scanf("%d %d",&i,&j);

//Intercambiar filas i y j

Intercambia_Filas(matriz,n,i,j);

//Mostrar la matriz

printf("\n***Matriz Modificada***");

Imprime_Matriz(matriz,m,n);

}

25

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema(Apartar memoria para la matriz)

/*

int **Aparta_Matriz(int m,int n);

Descripción: Aparta el espacio de memoria para la matriz dinámica

Recibe: int m (Número de filas), int n (Número de columnas)

Devuelve: int **matriz (Referencia a la matriz apartada),

Observaciones: m y n deberan ser mayor a 0

*/

int **Aparta_Matriz(int m,int n)

{

int i, **matriz;

//Apartar memoria para la matriz

matriz=malloc(m*sizeof(int)); //m apuntadores simples a enteros

for(i=0;i<m;i++)

matriz[i]=malloc(n*sizeof(int)); //El apuntador simple

matriz[i] apunta a n enteros

return matriz; //Regresa la referencia al apuntador principal a

la matriz dinámica

}

26

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema(Capturar la matriz)

/*

void Capturar_Matriz(int **matriz,int m,int n);

Descripción: Capturar la matriz dinámica

Recibe: int **matriz (Referencia a la matriz), int m (Número de filas),

int n (Número de columnas)

Devuelve:

Observaciones: La matriz fue reservada previamente de tamaño m por n

*/

void Capturar_Matriz(int **matriz,int m,int n)

{

int i,j;

for(i=0;i<m;i++)

for(j=0;j<n;j++)

{

printf("\nIntroduce el elemento[%d][%d]: ",i,j);

scanf("%d",&matriz[i][j]);

}

}

27

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema(Mostrar la matriz)

/*

void Imprime_Matriz(int **matriz,int m,int n);

Descripción: Procedimiento para imprimir la matriz

Recibe: int **matriz (Referencia a la matriz), int m (Número de

filas), int n (Número de columnas)

Devuelve:

Observaciones: La matriz fue reservada previamente de tamaño m

por n

*/

void Imprime_Matriz(int **matriz,int m,int n)

{

int i,j;

for(i=0;i<m;i++)

{

printf("\n");

for(j=0;j<n;j++)

printf("%d\t",matriz[i][j]);

}

}

28

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Problema(Intercambiar filas de la matriz)

/*

void Intercambia_Filas(int **matriz,int n,int i,int j);

Descripción: Procedimiento para intercambiar filas i y j de la matriz

Recibe: int **matriz (Referencia a la matriz), int n (Número de columnas)

int i e int j (Filas a intercambiar)

Devuelve:

Observaciones: La matriz fue reservada previamente de tamaño m por n

*/

void Intercambia_Filas(int **matriz,int n,int i,int j)

{

int x,aux,*aux2;

//Manera 1 (Cambiando de fila cada uno de los datos)

/*for(x=0;x<n;x++)

{

aux=matriz[j][x];

matriz[j][x]=matriz[i][x];

matriz[i][x]=aux;

}*/

//Manera 2 (Cambiando solo los apuntadores a cada fila)

aux2=matriz[i]; //Se puede escribir coomo aux2=*(matriz+i);

matriz[i]=matriz[j];//Se puede escribir coomo *(matriz+i)=*(matriz+j);

matriz[j]=aux2; //Se puede escribir coomo *(matriz+j)=aux2;

}

29

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez

Ejercicios 02: Programación con memoria dinámica

3030

• Programa de manera estructurada en ANSI C, un programa capaz degenerar y recibir dos matrices dinámicas de tamaño m por n, donde m yn ingresan por la entrada estándar, además de los valores de lasmatrices, el programa realiza una operación de suma y resta de matricesque se muestra por la salida estándar.

• Observaciones1. Construir un código modular (no todo en el main) y debidamente

documentado.2. Entregar un reporte con las pruebas (capturas de pantalla y

explicaciones de cada prueba).3. El reporte es individual y tiene portada, índice y encabezados de pagina

con número de pagina , titulo y nombre del alumno.4. Enviar vía Web en un archivo comprimido (ZIP, RAR o TAR), código y

reporte.

*Se entregará antes del día Lunes 22 de Agosto de 2016 (23:59:59 hora limite).

Estr

uct

ura

s d

e d

ato

sR

epas

o 0

2: A

pu

nta

do

res

y m

anej

o d

e m

emo

ria

din

ámic

aP

rof.

Edga

rdo

Ad

rián

Fra

nco

Mar

tín

ez