Mejores prácticas para evitar problemas con los punteros [duplicate]

6 minutos de lectura

¿Cuáles son los resultados realistas de los errores del programador relacionados con los punteros?

¿Qué ‘efectos negativos’ suceden cuando los programadores crean errores de puntero?

Son preferibles los ejemplos prácticos con código.

  • ¿Alguno de ustedes Brian, Charles Bailey, Tanascius, StarBlue, Xetius me dirá cómo diablos esta pregunta no está relacionada con la programación?

    – Pálido punto azul

    16 de septiembre de 2009 a las 13:36

  • De acuerdo con las preguntas frecuentes, las preguntas deben ser “detalladas y específicas”. Esta es una pregunta muy general, pedir “historias de guerra” indica que está invitando a una “discusión extendida”. Wiki o no, esto está fuera de los límites del tipo de pregunta que SO invita.

    –CB Bailey

    16 de septiembre de 2009 a las 13:44

  • lo siento, todavía no es una pregunta real: este es un tema de discusión de la extensión de un libro

    – Steven A. Lowe

    16 de septiembre de 2009 a las 13:51

  • @George Stocker-Personalmente, realmente interpreté eso como una pregunta sobre las mejores prácticas y por qué debería usarlas … no necesariamente como una pregunta sobre ‘una vez cuando yo …’ … al menos esa fue mi interpretación.

    – John Mac Intyre

    16 de septiembre de 2009 a las 13:54

  • Personalmente, voté para cerrar porque era demasiado genérico. En realidad, no me di cuenta de si era o no un wiki comunitario.

    – Brian

    16 de septiembre de 2009 a las 14:29

avatar de usuario
Ryan Michela

Cosas que pueden salir mal cuando los punteros se usan incorrectamente:

  1. Pérdidas de memoria – Asigna un puntero en un método y luego lo deja fuera del alcance sin desasignarlo correctamente. El puntero a la memoria en el montón ahora se pierde, pero la memoria permanece asignada. Liberar esta memoria ahora es extremadamente difícil. Más información de Wikipedia.

  2. Infracciones de acceso – Creas un puntero que apunta a una dirección de memoria a la que no tienes acceso, o que no existe. Después de todo, los punteros son solo números enteros y se pueden manipular como cualquier otro número. Cuando intente desreferenciar su puntero inválido, su programa se detendrá. Más información de Wikipedia.

  3. Errores de puntero nulo – Este es un caso especial de una violación de acceso. La forma correcta de “estacionar” un puntero, para que no apunte a nada en particular, es establecer su valor en cero o nulo. Intentar desreferenciar un puntero nulo detendrá su programa. Más información de Wikipedia.

  4. Desbordamientos de búfer – Asignas un puntero para un búfer de caracteres de 30 caracteres. Luego procede a transmitir la entrada del usuario (desde un socket, archivo, consola, etc.) a este búfer. Si no implementa correctamente las comprobaciones de delimitación del búfer, su programa podría poner potencialmente más de 30 caracteres en el búfer. Esto corromperá los datos almacenados junto al búfer en la memoria y posiblemente lo expondrá a un ataque de código malicioso. Más información de Wikipedia.

  5. Corrupción de memoria – Un puntero es simplemente un número entero que contiene la dirección de memoria de algo a lo que apunta. Como un número entero, aritmética de punteros se puede utilizar para manipular el valor del puntero en todo tipo de formas interesantes. Se pueden desarrollar errores sutiles si los cálculos del puntero salen mal. El puntero apuntará ahora a una ubicación desconocida en la memoria, y cualquier cosa podría pasar cuando se desreferencia.

  6. Problemas de cadenas terminadas en cero – Estos errores ocurren cuando las funciones de la biblioteca de cadenas que esperan cadenas terminadas en nulo reciben punteros de caracteres que no terminan en nulo. Las funciones de la biblioteca de cadenas continuarán procesando caracteres, uno a la vez, hasta que se encuentre un nulo, donde sea que esté. Una broma ilustra mejor este error.

  • Si no le importa, ¿puede mejorar su respuesta dando algún ejemplo (si corresponde)?

    – Pálido punto azul

    20 de octubre de 2009 a las 5:19

Sólo inicializando sus variables de puntero y una buena limpieza eliminará el 99% de sus problemas. Por buena limpieza, quiero decir; Desasignar memoria y establecer variables de puntero en nulo.

De lo contrario, necesita un diseño claro con respecto a pasar punteros y qué código es responsable de limpiar esa memoria. Si termina en una situación en la que no sabe qué código será el último en usar la memoria y debería estar limpiando, entonces tiene un olor a diseño que querrá arreglar para mantener su cordura.

  • O mejor aún, no uses punteros en primer lugar.

    – TED

    16 de septiembre de 2009 a las 14:17

  • O mejor aún, no uses punteros en primer lugar.

    – TED

    16 de septiembre de 2009 a las 14:17

Los resultados al desreferenciar un puntero incorrecto no están definidos, por lo que, por definición, Cualquier cosa puede suceder cuando te equivocas con un puntero. Es por eso que debe evitar usarlos cuando sea posible.

Los lenguajes C-ish están diseñados en torno al uso de punteros, y son dominantes en este momento, por lo que esto parecerá un consejo loco para algunos. Aconsejaría a las personas que busquen lenguajes que estén diseñados para minimizar el uso de punteros y verifiquen errores comunes, como Ada.

Mi anécdota de puntero favorita es la siguiente: una vez trabajé para un grupo en Florida que mantenía una simulación de vuelo en red de 3 helicópteros en Kurtland AFB en Nuevo México (la mayor parte del camino al otro lado del continente). Hubo un error de bloqueo que apareció un día. El técnico del sitio local no pudo arreglarlo, así que después de un mes más o menos, uno de nuestros ingenieros viajó para verlo. Dos semanas más tarde estaba desconcertado, así que contrataron a otro. Después de otro mes, nuestro ingeniero superior también fue enviado en avión para ayudar.

Un mes más tarde (todo el tiempo con la empresa pagando por 3 personas viviendo en hoteles, alquilando autos y volando de regreso cada dos fines de semana), localizaron el problema. Resultó que alguien estaba indexando uno más allá del final de una matriz (C tampoco tiene verificación de índice). Luego estaban tomando la basura que estaba en esa ubicación, pasándola a una segunda máquina a través de la red, y estaba usando ese valor como un índice de matriz. Dado que ese código también estaba en C, nuevamente sin verificación. Agarró la basura en ese lugar y la envió a una tercera máquina. Esa máquina usó la basura como un puntero y trató de quitarle la referencia. auge.

Entonces, un error en el código en una máquina estaba causando un bloqueo en dos máquinas eliminadas de la red. Se desperdiciaron miles de dólares y varios meses de tiempo precioso en su búsqueda. Todo porque usaron un lenguaje sin controles de rango.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad