Punteros y memoria

La aritmética de punteros en C y C++

En esta lección vas a recorrer los elementos de un arreglo con la aritmética de punteros en C y con iteradores en C++.

Introducción

Cuando sumas 1 a un puntero, no avanza un byte, sino que pasa al siguiente elemento del arreglo, porque el compilador calcula el desplazamiento según el tamaño del tipo. Así se puede usar un puntero para recorrer una zona de memoria continua como si fuera un arreglo.

Puntos importantes

  • Un puntero solo debe apuntar a un objeto que todavía existe, del tipo correcto, o valer null.
  • Cada zona de memoria reservada debe liberarse exactamente una vez.
  • Deja claro qué función es dueña de la memoria (ownership) y qué datos solo se leen (const).

Ejemplos de código C y C++

C
Ejecutar →
main.c
#include <stdio.h>

int main(void) {
    int values[] = {10, 20, 30, 40};
    int sum = 0;
    for (int *p = values; p < values + 4; ++p) sum += *p;
    printf("sum=%d distance=%td\n", sum, (values + 4) - values);
    return 0;
}
Resultado de la ejecución
sum=100 distance=4
C++
Ejecutar →
main.cpp
#include <iostream>
#include <vector>

int main() {
    std::vector values{10, 20, 30, 40};
    int sum = 0;
    for (auto it = values.begin(); it != values.end(); ++it) sum += *it;
    std::cout << "sum=" << sum << " distance="
              << std::distance(values.begin(), values.end()) << '\n';
}
Resultado de la ejecución
sum=100 distance=4

Comparación entre C y C++

El bucle empieza con el puntero p en el primer elemento y avanza hasta que p llega a la posición values + 4. En cada paso, *p obtiene el valor actual para sumarlo al total. La aritmética de punteros solo es válida dentro de un mismo arreglo, o justo después de su último elemento. En C++, los iteradores permiten recorrer de la misma forma muchos tipos de contenedores.

C

La propiedad y la liberación de la memoria dependen por completo del programador.

C++

Los contenedores y RAII liberan automáticamente los recursos cuando el objeto llega al final de su vida.

Ejercicios de práctica

Ejecuta las dos versiones y después modifica el código para ver la diferencia de seguridad que aporta cada lenguaje.

  • Prueba con punteros nulos y con fallos al reservar memoria.
  • Ejecuta el programa con AddressSanitizer y UndefinedBehaviorSanitizer para detectar errores de memoria.
  • Deja claro qué puntero es dueño de la memoria y cuál solo sirve para leer.

Practica con un reto

Usa lo que cubre esta lección para resolver un problema real. Cada reto se ejecuta en el navegador, con pruebas al instante y una revisión de IA.

Todos los retos