PDF de programación - 9. Punteros y memoria dinámica

Imágen de pdf 9. Punteros y memoria dinámica

9. Punteros y memoria dinámicagráfica de visualizaciones

Actualizado el 15 de Junio del 2021 (Publicado el 6 de Diciembre del 2018)
1.121 visualizaciones desde el 6 de Diciembre del 2018
3,0 MB
46 paginas
Creado hace 10a (04/09/2013)
Fundamentos de la programación

9

Grado en Ingeniería Informática
Grado en Ingeniería del Software
Grado en Ingeniería de Computadores
Facultad de Informática
Luis Hernández Yáñez
Universidad Complutense

Direcciones de memoria y punteros
Operadores de punteros
Punteros y direcciones válidas
Punteros no inicializados
Un valor seguro: NULL

Copia y comparación de punteros
Tipos puntero

Punteros a estructuras
Punteros a constantes y punteros constantes

Punteros y paso de parámetros
Punteros y arrays
Memoria y datos del programa
Memoria dinámica
Punteros y datos dinámicos
Gestión de la memoria
Errores comunes
Arrays de datos dinámicos
Arrays dinámicos

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Fundamentos de la programación: Punteros y memoria dinámica

849
854
864
866
867
868
873
875
877
879
883
886
891
895
907
911
916
928

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Fundamentos de la programación: Punteros y memoria dinámica

Página 849

Los datos en la memoria

...

i

int i = 5;

Todo dato se almacena en memoria:
Varios bytes a partir de una dirección
Dirección base
Dirección base
El dato (i) se accede a partir de su dirección base(0F03:1A38)
Dirección de la primera celda de memoria utilizada por el dato
El tipo del dato (int) indica cuántos bytes (4) requiere el dato:
(La codificación de los datos puede ser diferente; y la de las direcciones también)

00000000 00000000 00000000 00000101  5

00000000
00000000
00000000
00000101

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A37

0F03:1A38

0F03:1A3C

...

Fundamentos de la programación: Punteros y memoria dinámica

Página 850

Los punteros contienen direcciones de memoria

Un punterosirve para acceder a través de él a otro dato
El valor del puntero es la dirección de memoria base de otro dato
Indirección:
Indirección:
Acceso indirecto a un dato
Acceso indirecto a un dato
punt apuntaa i
punt apuntaa i

0F03:1A39

0F03:1A38

puntpunt

i

0F03:1A3A

punt

0F03:1A3B

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...
00
00
00
05
...
0F
03
1A
38
...

ii

5

¿Cuántas celdas ocupa?
¿Cuántas celdas ocupa?
¿Cómo se interpretan los 0/1?
¿Cómo se interpretan los 0/1?

¿De qué tipo es el dato apuntado?
¿De qué tipo es el dato apuntado?

Fundamentos de la programación: Punteros y memoria dinámica

Página 851

Los punteros contienen direcciones de memoria

¿De qué tipo es el dato apuntado?
La variable a la que apunta un puntero será de un tipo concreto
¿Cuánto ocupa? ¿Cómo se interpreta?
El tipo de variable apuntado se establece al declarar el puntero:
El puntero nombreapuntará a una variable del tipoindicado
El asterisco (*) indica que es un puntero a datos de ese tipo
El puntero puntapuntará a una variable entera (int)

int *punt; // punt inicialmente contiene una dirección

// que no es válida (no apunta a nada)

tipo *nombre;

int i; // Dato entero  vs. int *punt; // Puntero a entero

Fundamentos de la programación: Punteros y memoria dinámica

Página 852

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Los punteros contienen direcciones de memoria

// que no es válida (no apunta a nada)

int *punt; // punt inicialmente contiene una dirección

Las variables puntero tampoco se inicializan automáticamente
Al declararlas sin inicializador contienen direcciones no válidas
Un puntero puede apuntar a cualquier dato de su tipo base
Un puntero no tiene por qué apuntar necesariamente a un dato
(puede no apuntar a nada: valor NULL)
Para implementar el paso de parámetros por referencia
Para manejar datos dinámicos
(Datos que se crean y destruyen durante la ejecución)
Para implementar los arrays

¿Para qué sirven los punteros?

Fundamentos de la programación: Punteros y memoria dinámica

Página 853

Fundamentos de la programación: Punteros y memoria dinámica

Página 854

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Obtener la dirección de memoria de ...

&&

int i;
cout << &i; // Muestra la dirección de memoria de i

Operador monario y prefijo
&devuelve la dirección de memoria base del dato al que precede
Un puntero puede recibir la dirección de datos de su tipo base
Ahora puntya contiene una dirección de memoria válida
punt apuntaa (contiene la dirección de) la variable i(int)

int i;
int *punt;
punt = &i; // punt contiene la dirección de i

puntpunt

ii

Fundamentos de la programación: Punteros y memoria dinámica

Página 855

Obtener la dirección de memoria de ...

&&

int i, j;
...
int *punt;

i

j

punt

...

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...

Fundamentos de la programación: Punteros y memoria dinámica

Página 856

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

&&

&&

Obtener la dirección de memoria de ...

int i, j;
...
int *punt;
...
i = 5;

ii

5

00
00
00
05

i

j

punt

...

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...

Fundamentos de la programación: Punteros y memoria dinámica

Página 857

Obtener la dirección de memoria de ...

int i, j;
...
int *punt;
...
i = 5;
punt = &i;

i

j

puntpunt

punt

ii

5

...

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...

00
00
00
05

0F
03
1A
38

Fundamentos de la programación: Punteros y memoria dinámica

Página 858

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Obtener lo que hay en la dirección ...

**

Operador monario y prefijo
*accede a lo que hay en la dirección de memoria a la que precede
Permite acceder a un dato a través un puntero que lo apunte:
*punt: lo que hay en la dirección que contiene el puntero punt
puntcontiene la dirección de memoria de la variable i
*puntaccede al contenido de esa variable i
Acceso indirecto al valor de i

punt = &i;
cout << *punt; // Muestra lo que hay en la dirección punt

Fundamentos de la programación: Punteros y memoria dinámica

Página 859

Obtener lo que hay en la dirección ...

**

int i, j;
...
int *punt;
...
i = 5;
punt = &i;
j = *punt;

punt:
punt:

i

j

punt

...

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...

00
00
00
05

0F0F
0F
0303
03
1A1A
1A
3838
38

Fundamentos de la programación: Punteros y memoria dinámica

Página 860

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

**

**

Obtener lo que hay en la dirección ...

int i, j;
...
int *punt;
...
i = 5;
punt = &i;
j = *punt;

Direccionamiento
Direccionamiento

indirecto 
indirecto 

(indirección)
(indirección)

Se accede al dato i
Se accede al dato i
de forma indirecta
de forma indirecta

*punt:
*punt:

i

j

punt

...

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...

0000
00
0000
00
0000
00
0505
05

0F
03
1A
38

Fundamentos de la programación: Punteros y memoria dinámica

Página 861

Obtener lo que hay en la dirección ...

int i, j;
...
int *punt;
...
i = 5;
punt = &i;
j = *punt;

i

j

punt

...

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

0F07:0417

0F07:0418

0F07:0419

0F07:041A

...

00
00
00
05
0000
0000
0000
0505

0F
03
1A
38

Fundamentos de la programación: Punteros y memoria dinámica

Página 862

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

punteros.cpp
punteros.cpp

Ejemplo de uso de punteros

#include <iostream>
using namespace std;

int main() {
int i = 5;
int j = 13;
int *punt;
punt = &i;
cout << *punt << endl; // Muestra el valor de i
punt = &j;
cout << *punt << endl; // Ahora muestra el valor de j
int *otro = &i;
cout << *otro + *punt << endl; // i + j
int k = *punt;
cout << k << endl; // Mismo valor que j

return 0;

}

Fundamentos de la programación: Punteros y memoria dinámica

Página 863

Fundamentos de la programación: Punteros y memoria dinámica

Página 864

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Todo puntero ha de tener una dirección válida

Un puntero sólo debe ser utilizado si tiene una dirección válida
Un puntero NO contiene una dirección válida tras ser definido
Un puntero obtiene una dirección válida:
Asignando la dirección de otro dato (operador &)
Asignando otro puntero (mismo tipo base) que ya sea válido
Asignando el valor NULL(puntero nulo, no apunta a nada)

int i;
int *q; // q no tiene aún una dirección válida
int *p = &i; // p toma una dirección válida
q = p; // ahora q ya tiene una dirección válida
q = NULL; // otra dirección válida para q

Fundamentos de la programación: Punteros y memoria dinámica

Página 865

Punteros que apuntan a saber qué...

int *punt; // No inicializado
*punt = 12; // ¿A qué dato se está asignando el valor?
¿Dirección de la zona de datos del programa?

Un puntero no inicializado contiene una dirección desconocida
¡Podemos modificar inadvertidamente un dato del programa!
¡Podemos modificar el código del propio programa!
¡Podemos modificar el código del propio S.O.!
Consecuencias imprevisibles (cuelgue)
(Los S.O. modernos protegen bien la memoria)

¿Dirección de la zona de código del programa?

¿Dirección de la zona de código del sistema operativo?

Fundamentos de la programación: Punteros y memoria dinámica

Página 866

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

z
e
ñ
á
Y
 
z
e
d
n
á
n
r
e
H
 
s
i
u
L

Punteros que no apuntan a nada

int *punt = NULL;
...
*punt = 13;

Inicializando los punteros a NULLpodemos detectar errores:
puntha sido inicializado a NULL: ¡No apunta a nada!
Si no apunta a nada, ¿¿¿qué significa *punt??? No tiene sentido
ERROR: ¡Acceso a un dato a través de un puntero nulo!
Error de ejecución, lo que ciertamente no es bueno
Pero s
  • Links de descarga
http://lwp-l.com/pdf14447

Comentarios de: 9. Punteros y memoria dinámica (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad