Estructuras de datos

Apuntadores

Un apuntador (pointer) es, en pocas palabras, una variable que almacena la dirección de memoria de otra variable

 

Esto nos permite manipular información directamente en memoria sin necesidad de usar la variable que contiene dicha información

 

El concepto de un apuntador es, de facto, la parte medular de la manipulación de memoria a bajo nivel en C

Apuntadores

En este ejemplo ocurren varias cosas:

  1. Inicializamos una variable (var)
  2. Inicializamos un apuntador (ptr)
  3. ¿Qué es lo que se imprime?

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%d", ptr);
    
    return 0;
}

En este ejemplo ocurren varias cosas:

  1. Inicializamos una variable (var)
  2. Inicializamos un apuntador (ptr)
  3. ¿Qué es lo que se imprime?

 

El operador * es un operador de indirección (o de dereferencia) y nos permite acceder al valor que está almacenado en la dirección de memoria del apuntador

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%d", ptr);
    
    return 0;
}

En este ejemplo ocurren varias cosas:

  1. Inicializamos una variable (var)
  2. Inicializamos un apuntador (ptr)
  3. ¿Qué es lo que se imprime?

 

El operador & es un operador de referencia y nos permite obtener la dirección de memoria de una variable

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%d", ptr);
    
    return 0;
}

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%d", ptr);
    
    return 0;
}

¿Qué pasa con el siguiente código?

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%d", *ptr);
    
    return 0;
}

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%d", *ptr);
    
    return 0;
}

En C, hay un especificador de formato propio de apuntadores

Apuntadores

#include <stdio.h>

int main() {
    int var = 10;
    
    //Guardamos la dirección de la variable var
    int* ptr = &var;
    
    //Accedemos directamente al apuntador
    printf("%p", *ptr);
    
    return 0;
}

El tamaño en memoria de un apuntador depende exclusivamente de la arquitectura de la computadora donde se ejecute el código y absolutamente nunca depende del tipo de dato al que apunte:

  • 4 bytes en sistemas de 32 bits
  • 8 bytes en sistemas de 64 bits

Tamaño de un apuntador

#include <stdio.h>

int main() {
    int *ptr1;
    char *ptr2;
    
    printf("%zu\n", sizeof(ptr1));
    printf("%zu", sizeof(ptr2));
    
    return 0;
}

Un apuntador nulo (o apuntador a nulo) no apunta a ninguna dirección de memoria de modo que se usa para representar la ausencia de una dirección

 

Básicamente es la forma en la que podemos saber si el apuntador está apuntando a algo (sea lo que sea ese algo) o a nada

 

Siempre, pero siempre, del verbo nunca jamás lo olviden, inicialicen sus apuntadores a nulo

Apuntador nulo

#include <stdio.h>

int main() {
    
    int *ptr = NULL;
    
    return 0;
}

Un apuntador vacío (o genérico) no tiene ningún tipo de dato asociado de modo que puede apuntar, o castearse, a cualquier tipo de dato

Apuntador vacío

#include <stdio.h>

int main() {

    void *ptr;
    
    return 0;
}

Un apuntador salvaje es cualquier apuntador que no ha sido inicializado

 

Pueden y van a causar problemas de memoria

 

No, no es una probabilidad, van a causar problemas de memoria

  • Cuando tengan algún error de falla de segmentación seguramente es por algún apuntador salvaje

Apuntador salvaje

#include <stdio.h>

int main() {

    int *ptr;
    
    return 0;
}

Un apuntador colgante es un apuntador que apuntaba a una dirección de memoria que ha sido borrada o liberada

 

Suelen ser la causa de muchos problemas en C

Apuntador colgante

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int));

    free(ptr);
    printf("Memoria liberada\n");

    return 0;
}

Un apuntador colgante es un apuntador que apuntaba a una dirección de memoria que ha sido borrada o liberada

 

Suelen ser la causa de muchos problemas en C

  • Cuando tengan algún error de falla de segmentación seguramente es por algún apuntador colgante

 

Podemos evitar un apuntador colgante mandándolo a nulo

Apuntador colgante

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int));

    free(ptr);
    ptr = NULL;
    printf("Memoria liberada\n");

    return 0;
}

Podemos realizar algunas operaciones aritméticas con los apuntadores:

  • Incrementar/decrementar
  • Suma y resta de enteros
  • Resta de dos apuntadores del mismo tipo
  • Comparación/asignación de dos apuntadores del mismo tipo
  • Comparación/asignación con nulo

Aritmética de apuntadores

Además de hacerlos sufrir en clase, los apuntadores se usan para:

  • Paso de parámetros por referencia
  • Acceder elementos de arreglos
  • Regresar más de un valor de una función
    • Técnicamente no regresan nada, más bien manipulan los valores en memoria
  • Asignación de memoria dinámica
  • Implementación de diversas estructuras de datos
  • Tablas de control

Uso de apuntadores

Algunas de las ventajas del uso de apuntadores son:

  • Asignación y liberación de memoria dinámica
  • Acceso eficiente a estructuras o arreglos
  • Creación de estructuras de datos complejas como listas ligadas, árboles y grafos
  • Torturar estudiantes
  • Reducen el tiempo de ejecución y longitud de un programa

Ventajas del uso de apuntadores

Algunos de los problemas del uso de apuntadores son:

  •  

Contras del uso de apuntadores

Estructuras de datos: Apuntadores

By Gilberto 🦁

Estructuras de datos: Apuntadores

Apuntadores

  • 139