¿Cuáles son los principales problemas con los punteros en la programación C / C ++?

¡Nada te meterá en más problemas que un puntero salvaje! Los punteros son una bendición mixta. Le dan un poder tremendo, pero cuando un puntero se usa incorrectamente o contiene un valor incorrecto, puede ser un error muy difícil de encontrar.

Es difícil encontrar un puntero erróneo porque el puntero, por sí mismo, no es el problema. El problema comienza cuando accede a un objeto a través de ese puntero. En resumen, cuando intentas usar un puntero incorrecto, estás leyendo o escribiendo en algún trozo de memoria desconocido. Si lo lees, obtendrás un valor basura, lo que probablemente hará que tu programa no funcione correctamente. Si le escribe, podría estar escribiendo sobre otras partes de su código o datos. En cualquier caso, el problema puede no aparecer hasta más tarde en la ejecución de su programa y puede llevarlo a buscar el error en el lugar equivocado. Puede haber poca o ninguna evidencia que sugiera que el puntero sea la causa original del problema. Los programadores pierden el sueño por este tipo de error una y otra vez.

Debido a que los errores de puntero son tan problemáticos, por supuesto, debe hacer su mejor esfuerzo para nunca generar uno. Para ayudarlo a evitarlos, aquí se analizan algunos de los errores más comunes. El ejemplo clásico de un error de puntero es el puntero no inicializado. Considere este programa:

/ * Este programa está mal. * /
int main (nulo)
{
int x, * p;
x = 10;
* p = x; / * error, p no inicializado * /
devuelve 0;
}

Este programa asigna el valor 10 a alguna ubicación de memoria desconocida. Aquí es por qué. Como el puntero p nunca ha recibido un valor, contiene un valor desconocido cuando se realiza la asignación *p = x . Esto hace que el valor de x se escriba en alguna ubicación de memoria desconocida. Este tipo de problema a menudo pasa desapercibido cuando el programa es pequeño porque las probabilidades están a favor de que p contenga una dirección ” segura “, una que no está en su código, área de datos o sistema operativo. Sin embargo, a medida que su programa crece, aumenta la probabilidad de que p apunte a algo vital. Eventualmente, su programa deja de funcionar. En este simple ejemplo, la mayoría de los compiladores emitirán un mensaje de advertencia que indica que está intentando utilizar un puntero no inicializado, pero el mismo tipo de error puede ocurrir en más formas indirectas que el compilador no puede detectar.

Un segundo error común es causado por un simple malentendido sobre cómo usar un puntero. Considera lo siguiente:

/ * Este programa está mal. * /
#include
int main (nulo)
{
int x, * p;
x = 10;
p = x;
printf (“% d”, * p);
devuelve 0;
}

La llamada a printf( ) no imprime el valor de x, que es 10, en la pantalla. Imprime algún valor desconocido (o dirección) porque la asignación

p = x;

Está Mal. Esa declaración asigna el valor 10 al puntero p. Sin embargo, se supone que p contiene una dirección, no un valor. Para corregir el programa, escriba

p = & x;

Al igual que con el error anterior, la mayoría de los compiladores emitirán al menos un mensaje de advertencia cuando intentes asignar x a p. Pero como antes, este error puede manifestarse de una manera más sutil que el compilador no puede detectar.

Otro error que a veces ocurre es causado por suposiciones incorrectas sobre la colocación de variables en la memoria. En general, no puede saber dónde se colocarán sus datos en la memoria, o si se colocarán allí de la misma manera, o si diferentes compiladores los tratarán de la misma manera. Por estas razones, hacer cualquier comparación entre punteros que no apuntan a un objeto común puede producir resultados inesperados.

Por ejemplo:

char s [80], y [80];
char * p1, * p2;
p1 = s;
p2 = y;
si (p1 <p2). . .

es generalmente un concepto inválido. (En situaciones muy inusuales, puede usar algo como esto para determinar la posición relativa de las variables. Pero esto sería raro).

Se produce un error relacionado cuando supone que dos matrices adyacentes pueden indexarse ​​como una simplemente incrementando un puntero a través de los límites de la matriz.

Por ejemplo:
int primero [10], segundo [10];
int * p, t;
p = primero;
para (t = 0; t <20; ++ t) * p ++ = t;

Esta no es una buena manera de inicializar las matrices primero y segundo con los números del 0 al 19. Aunque puede funcionar en algunos compiladores bajo ciertas circunstancias, se supone que ambas matrices se colocarán de nuevo en la memoria con el primero primero. Esto puede no ser siempre el caso.

El siguiente programa ilustra un tipo de error muy peligroso . Mira si puedes encontrarlo.

/ * Este programa tiene un error. * /
#include
#include
int main (nulo)
{
char * p1;
char s [80];
p1 = s;
hacer {
obtiene (s); / * leer una cadena * /
/ * imprime el equivalente decimal de cada carácter * /
mientras que (* p1)
printf (“% d”, * p1 ++);
} while (strcmp (s, “hecho”));
devuelve 0;
}

Este programa usa p1 para imprimir los valores ASCII asociados con los caracteres contenidos en s . El problema es que a p1 se le asigna la dirección de s solo una vez, fuera del bucle. La primera vez a través del ciclo, p1 apunta al primer carácter en s . Sin embargo, la segunda vez, continúa donde lo dejó porque no se restablece al inicio de s . ¡El siguiente carácter puede ser parte de la segunda cadena, otra variable o una parte del programa! La forma correcta de escribir este programa es:

/ * Este programa ahora es correcto. * /
#include
#include
int main (nulo)
{
char * p1;
char s [80];
hacer {
p1 = s; / * restablecer p1 al comienzo de s * /
obtiene (s); / * leer una cadena * /
/ * imprime el equivalente decimal de cada carácter * /
mientras que (* p1)
printf (“% d”, * p1 ++);
} while (strcmp (s, “hecho”));
devuelve 0;
}

Aquí, cada vez que el ciclo itera, p1 se establece al comienzo de la cadena. En general, debe recordar reinicializar un puntero si se va a reutilizar. El hecho de que el manejo incorrecto de los punteros pueda causar errores difíciles no es motivo para evitar usarlos. Solo tenga cuidado y asegúrese de saber a dónde apunta cada puntero antes de usarlo.

Muchas gracias. Sigan codificando !!!

El problema al usar un puntero ocurre en el momento en que devolvemos un puntero desde una función distinta de la función principal.

Como os call es una función, la función obtendrá algo de memoria en RAM para su ejecución. Como estamos devolviendo un puntero a través de esta función, apuntará a alguna dirección ubicada en el área de memoria dada la función que se llama. También podemos acceder al valor en esta dirección mediante el puntero a esta dirección. Pero el problema surge cuando se detiene la ejecución de la función llamada, es decir, se elimina de la memoria en la RAM. Por lo tanto, el puntero que regresa apuntará a algún valor basura porque el valor original almacenado en la dirección señalada por el puntero obtiene los cambios a medida que la función se elimina de la memoria.

Entonces, en lugar de señalar un valor útil, el puntero apuntará a un valor basura.

Por favor, consulte el siguiente enlace:

Punteros en C y C ++ | Conjunto 1 (Introducción, Aritmética y Array) – GeeksforGeeks

Los punteros pueden acceder directamente a cualquier ubicación de memoria, y acceder a cualquier memoria directa es perjudicial para nuestro código fuente.