¿Pueden varios punteros hacer referencia a la misma variable en C?

2

Es una peculiaridad de C que a menudo hace tropezar a los principiantes, pero que se siente como magia una vez que hace clic: puedes tener una docena de punteros, todos mirando a la misma dirección de memoria.

Considere este escenario. Declaras un número entero i. Luego declara tres punteros p, q y r. Los asignas todos a la dirección de “i”.

Mira esa última línea. r no necesita saber acerca de i directamente. Simplemente apunta a lo que sea que apunte “p”. Y “p” apunta a “i”. Entonces “r” también apunta a “i”.

El operador de asignación aquí copia la dirección, no el valor. Cuando haces r = p, no estás copiando el número entero dentro de i. Estás copiando la ubicación de memoria que contiene p.

Después de ejecutar este código, i esencialmente tiene cuatro nombres. Puede acceder a él a través de i. Puede acceder a él a través de *p. Puede acceder a él a través de *q. O puede acceder a él a través de *r.

No hay límite técnico sobre la cantidad de punteros que puedes acumular de esta manera.

Por qué esto es importante

Esto no es sólo sintaxis académica. Cambia su forma de pensar sobre el flujo de datos.

En lenguajes con referencias estrictas a objetos, copiar un objeto a menudo crea una nueva instancia en la memoria. En C, copiar un puntero es barato. Es sólo una dirección de memoria. Rápido. Diminuto.

Esto permite que varias partes de su código manipulen los mismos datos sin duplicación. Cambie *p y *q ve el cambio inmediatamente.

Estás creando alias para la memoria.

El riesgo de alias

Aquí es donde el “aspecto genial” se convierte en un inconveniente.

Si p, q y r apuntan a i, cualquiera de ellos puede modificar i.

Ahora i es 10. *q es 10. *r es 10.

Pero, ¿qué pasa si olvidas que “r” también está mirando a “i”? Podrías asumir que “i” es estable porque no lo has tocado directamente. Solo tocaste *q.

Es un recurso compartido. Y los recursos compartidos son el lugar donde viven las condiciones de carrera y las sobrescrituras inesperadas.

Cómo prevenir efectos secundarios no deseados

Si desea asegurarse de que un puntero no sobrescriba accidentalmente los datos destinados a otro, utilice “const”.

Ahora r puede leer i. Puede señalarlo. No puede cambiarlo.

Así es como se imponen límites en un lenguaje que confía en usted para administrar la memoria manualmente.

Dónde encaja esto en la programación de sistemas

Este patrón se ve en todas partes del código de sistemas.

Las estructuras del kernel suelen tener varios punteros al mismo bloque de control. Los controladores de dispositivos asignan el mismo registro de hardware a diferentes nombres lógicos.

Comprender que los punteros son solo etiquetas para direcciones le ayudará a depurar estos problemas. Cuando la memoria se corrompe, sigue los consejos. ¿Quién más?