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

Imágen de pdf 9. Punteros y memoria dinámica - Fundamentos de la programación

9. Punteros y memoria dinámica - Fundamentos de la programacióngráfica de visualizaciones

Actualizado el 17 de Enero del 2019 (Publicado el 11 de Enero del 2019)
249 visualizaciones desde el 11 de Enero del 2019
2,3 MB
47 paginas
Creado hace 4a (13/05/2014)
13/05/2014

Fundamentos de la programación 

2013‐2014

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 de punteros

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
Inicialización de datos dinámicos
Errores comunes
Arrays de datos dinámicos
Arrays dinámicos

2
7
17
19
20
21
26
28
30
32
36
39
44
48
61
64
66
71
83

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 1

1

13/05/2014

Página 2

5

...

...

00000000
00000000
00000000
00000101

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

Los datos en la memoria

Todo dato (variable o constante) de un programa se almacena
en la memoria: en unos cuantos bytes a partir de una dirección.

int i = 5;

Dirección base
Dirección base

i

0F03:1A37

0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

El dato (i) se accede a partir de su dirección base(0F03:1A38),
la dirección de la primera celda de memoria utilizada por ese dato.
El tipo del dato (int) indica cuántas celdas (bytes) utiliza ese dato (4):
(La codificación de los datos puede ser diferente. Y la de las direcciones también.)

00000000 00000000 00000000 00000101  5

0F03:1A3C

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

Página 3

2

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

13/05/2014

Los punteros contienen direcciones de memoria

Una variable puntero(o simplemente puntero) sirve para acceder
a través de ella a otro dato del programa.
El valor del puntero será 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

ii

5

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

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

i

0F03:1A3A

punt

0F03:1A3B

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 4

Los punteros contienen direcciones de memoria

¿De qué tipo es el dato apuntado?
La variable a la que apunta un puntero, como cualquier otra variable,
será de un tipo concreto (¿cuánto ocupa? ¿cómo se interpreta?).
El tipo de variable a la que apunta un puntero se establece
al declarar la variable puntero:
El puntero nombreapuntará a una variable del tipoindicado
(el tipo base del puntero).
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 5

3

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

13/05/2014

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 que no son válidas.
Un puntero puede apuntar a cualquier dato del 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 qué sirven los punteros?

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

Página 6

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

Página 7

4

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

El operador monario &devuelve la dirección de memoria base
del dato al que se aplica el operador. Operador prefijo (precede).
A un puntero se le puede asignar la dirección base de cualquier dato
del mismo tipo que el tipo base del puntero:
Ahora, el puntero puntya contiene una dirección de memoria válida.
punt apuntaa (contiene la dirección base de) la variable entera i(int).

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

&&

puntpunt

ii

5

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

Página 8

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 9

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

13/05/2014

5

&&

&&

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 10

Obtener la dirección de memoria de ...

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

puntpunt

ii

5

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

0F
03
1A
38

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

Página 11

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

13/05/2014

6

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

**

El operador monario *accede a lo que hay en la dirección de memoria
a la que se aplica el operador (un puntero). Operador prefijo (precede).
Una vez que un puntero contiene una dirección de memoria válida,
se puede acceder al dato al que apunta con este operador.
*punt: lo que hay en la dirección que contiene el puntero punt.
Como el puntero puntcontiene la dirección de memoria de
la variable i, *puntaccede al contenido de esa variable i.
Acceso indirecto al valor de i.
Se obtienen, a partir de la dirección de memoria base que contiene
punt, tantos bytes como correspondan al tipo base (int) (4) y se
interpretan como un dato de ese tipo base (int).

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 12

Obtener la dirección de memoria de ...

**

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
03
0303
1A
1A1A
3838
38

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

Página 13

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

13/05/2014

7

Obtener la dirección de memoria de ...

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

...

00
0000
00
0000
00
0000
05
0505

0F
03
1A
38

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

Página 14

Obtener la dirección de memoria de ...

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 15

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

**

**

13/05/2014

8

13/05/2014

Ejemplo de uso de punteros

#include <iostream>
using namespace std;

punteros.cpp

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 16

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

Página 17

9

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

13/05/2014

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

Un puntero sólo debe ser utilizado para acceder al dato al que apunte,
si se está seguro de que contiene 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:
 Al copiarle otro puntero (con el mismo tipo base)
que ya contenga una dirección válida.
 Al asignarle la dirección de otro dato con el operador &.
 Al asignarle el valor NULL(indica que se trata de un puntero nulo,
un puntero que 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 = NULL; // ahora q ya tiene una dirección válida
q = p; // otra dirección válida para q

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

Página 18

Punteros que apuntan a saber qué...

int *punt; // no inicializado
*punt = 12;
¿Dirección de la zona de datos del pr
  • Links de descarga
http://lwp-l.com/pdf14815  

Comentarios de: 9. Punteros y memoria dinámica - Fundamentos de la programación (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad

Revisar política de publicidad