Los punteros son una de las herramientas más poderosas del lenguaje C++. Permiten manipular directamente direcciones de memoria y crear estructuras de datos flexibles, como arreglos dinámicos. En este artículo, aprenderás a usar punteros de forma segura, reservando y liberando memoria correctamente, y accediendo a los valores mediante aritmética de punteros.
[ESTRUCTURA DE DATOS] ESTRUCTURA DE DATOS: PUNTEROS Y MEMORIA DINÁMICA EN C++
Para entender el comportamiento de los punteros y cómo se usan estos en el manejo de vectores, debemos verlo a nivel de código, que es lo más adecuado para comprender lo mencionado, dicho lo anterior, procedamos con algunos ejemplos:
Reserva de memoria dinámica
Para ver este caso, analicemos el siguiente código:
int* start = new int[elementQuantity];
x = start;
En el código anterior se reserva un bloque de memoria del tamaño solicitado por el usuario, y x apunta al inicio del arreglo. Usamos un puntero auxiliar start para no perder la dirección original, lo cual es importante para liberar la memoria correctamente.
Ingreso de datos
En esta parte, asumamos que ya tenemos un bucle con el número de elementos a rercorrer para ir ingresando los datos, por lo tanto, el ingreso de datos propiamente dicho, será de la siguiente manera:
std::cin >> *(x + i);
En el código anterior se usa aritmética de punteros para acceder a cada posición del arreglo como si fuera x[i].
Impresión de datos
Tal como en el caso anterior, la impresión de datos manejaría la misma estrategia del acceso a los valores, por lo que no habría más que explicar y solo mostramos el siguiente código:
std::cout << *(x + i);
Exploración de direcciones
Veamos el siguiente código:
std::cout << x << " -> " << *x << std::endl;
std::cout << x + 1 << " -> " << *(x + 1) << std::endl;
std::cout << x + 2 << " -> " << *(x + 2) << std::endl;
El código anterior muestra la dirección en memoria de cada elemento y su contenido lo cual es útil para visualizar cómo se distribuyen los datos en la RAM, además, aquel código muestra los datos correctos solo si el usuario ha ingresado 3 o más elementos, y, en caso se haya ingreado menos elementos, se dará salto a posiciones de memoria desconocida y mostrará los valores que almacene dichas posiciones de memoria.
Liberación de memoria
Para este caso, usamos el siguiente código:
delete[] start;
Usamos delete[] para liberar el bloque completo de memoria que reservamos con new[]. Esto es crucial para evitar fugas de memoria.
Código completo de este ejemplo
Seguidamente se brinda el código completo de las secciones presentadas previamente:
#include <iostream>
int main() {
unsigned int elementQuantity;
int *x;
std::cout << "Ingrese cantidad de elementos para el vector: ";
std::cin >> elementQuantity;
int *start = new int[elementQuantity];
x = start;
for(unsigned int i = 0; i < elementQuantity; i++) {
std::cout << "Ingrese valor para el elemento [" << i << "]: ";
std::cin >> *(x + i);
}
for(unsigned int i = 0; i < elementQuantity; i++) {
std::cout << *(x + i) << std::endl;
}
std::cout << "-------------------------------" << std::endl << std::endl;
std::cout << x << " -> " << *x << std::endl;
std::cout << x + 1 << " -> " << *(x + 1) << std::endl;
std::cout << x + 2 << " -> " << *(x + 2) << std::endl;
delete[] start;
return 0;
}
CONCLUSIÓN
Los punteros en C++ permiten gestionar memoria dinámica de manera eficiente, facilitando la creación, acceso y liberación de arreglos. Usar new[] y delete[] correctamente evita fugas de memoria, mientras que la aritmética de punteros (*(x + i)) simplifica el manejo de datos. Es crucial conservar la dirección base (start) y validar los accesos para evitar comportamientos indefinidos al operar fuera de los límites asignados.
No hay comentarios:
Publicar un comentario