Qué hacer con un fallo de segmentación 11
Por alguna razón, decidí construir un producto usando C. Si el objetivo era la eficiencia del código, fue un desastre. Pero como herramienta para el crecimiento personal, creo que aprendí mucho más sobre programación en el proceso.
Por ejemplo, ahora sé con más precisión por qué un diccionario python y una lista se comportan de manera diferente, y lo que realmente significa «pasar por referencia».»
Sin embargo, si hubiera una barrera que me hiciera no querer volver a C, sería la temida» Falla de Segmentación 11″, seguida de cerca por «Trampa Abortada 6″.»
Estos dos errores ocurren durante el tiempo de ejecución, lo que los hace difíciles de depurar. XCode, Eclipse u otras herramientas de depuración son realmente útiles, pero he aprendido que es mucho más importante aprender qué son estas cosas y crear procedimientos para abordar el proceso de depuración. Estas son solo mis notas sobre mis propios errores comunes. Espero hacer de esta una lista de solución de problemas para cualquiera que tenga sus propios problemas. Al menos quiero cubrir mis estúpidos problemas, para que puedas concentrarte en problemas reales de codificación.
Un error de segmentación significa que su programa intentó acceder a algo que no debía. Eso es parte del problema. Hay muchas razones por las que un programa puede acceder a cosas que no se supone que debe, pero el código compilado simplemente dice «#@# @ ^*&!»en su lugar. Si lo piensas bien, no querrás tener que explicarle a alguien por qué meterte en un lugar sensible te hace enojar. Solo quieres que dejen de hacerlo. Afortunadamente, las computadoras son tontas y sorprendentemente pacientes después de unos 75 años de ingeniería. Seguirán enviando fallas de Seg, pero (por lo general) no dejarán de ser amigos después de que ocurra la 1000a vez.
¿Qué es la trampa de aborto?
no Es muy diferente. En algún lugar, su computadora se dijo a sí misma que abortara el programa. De nuevo, no es muy útil. Sin embargo, generalmente ocurre cuando intenta hacer algo como acceder string
de una cadena de dos caracteres "nw"
o no puede asignar suficiente memoria char string
para una cadena o matriz como "way"
.
¿Qué Debe Hacer con un Fallo Seg?
Los tutoriales que leo tienden a centrarse en el uso de herramientas de depuración como lldb, gdb, etc. Todo eso está bien y elegante. Sí, primero debe ejecutar gcc -g
y luego lldb executable_name
y luego run -flag1 -flag2
para ver si eso le ayuda a averiguarlo. Pero a veces no hay ayuda en absoluto. Tengo una lista de cosas que verificar.
- Compruebe que las variables globales de su programa necesarias tengan valores. Esto sucedió principalmente porque había creado banderas que llenaban un montón de valores que debían establecerse antes de ejecutarse. Sin embargo, ¿qué pasa si no ponen nada? ¡Fallo de Seguridad 11! Hubo un número de veces que* pensé * que los var estaban configurados cuando no lo estaban y eso estaba hecho para errores desafiantes. Mejor aún, trate de mantener los globales al límite para que sean más fáciles de rastrear.
- malloc es tanto tu amigo como tu enemigo. Especialmente con las entradas de usuario, puede ser muy difícil asignar memoria y luego copiar, concatenar y hacer cualquier otra cosa en el futuro. Conozca bien este comando y cómo funciona. Y no se olvide de
free()
la memoria cuando haya terminado! - use
char var
para determinar el tamaño de un carácter * para la asignación de memoria. La mayor parte del problema que tenía consistía en asignar variables para aceptar eventualmente una cadena. He visto otros consejos, pero si es una cadena con la que está trabajando, creo questrlen()
funcionó de la manera más consistente. Necesita el +1 para\0
(null) para terminar la cadena al final. - use
int arr) +1)]
para matrices de otros tipos. Es una forma extraña de hacer las cosas, pero eso es lo que se obtiene con un lenguaje de bajo nivel. -
\0
representa null y terminará un array. Puede ser útil cuando intenta evitar problemas de desbordamiento de búfer. - Intente usar constantes definidas tanto como sea posible. Siempre que pueda definir cosas en precompilar, le ahorrará tiempo de depuración más adelante.
- Entender para qué sirven los archivos de encabezado. Muchos de los tutoriales le dirán lo que contiene un archivo de encabezado, pero no siempre está claro para qué sirven. Los archivos de cabecera se capturan en tiempo de pre-compilación y proporcionan un resumen de las variables y funciones disponibles para el programa * antes de que se compile*. Esto significa que el .los archivos c incluidos en el programa podrán acceder a estas funciones, siempre que
#include <headerfile.h>
se agregue al archivo. Una buena convención es crear un .archivo h cada vez que se crea un .la mayoría de los bucles for son así:for (int i=0; i < stop; i++)
Una forma fácil de tener una trampa de aborto es poner a ≤ delante destop
. - Mantenga sus problemas contenidos. Trate de hacer que cada archivo haga algunas cosas discretas y nada más. Si tiene que buscar entre diferentes archivos, puede hacer que encontrar sus problemas de fallas de seg sea realmente difícil.
- Las matemáticas de computadora son difíciles. No lo es, pero las pequeñas cosas causan grandes problemas.
char variable
por ejemplo, significa una matriz que contiene dos elementos, pero como los índices comienzan en 0, eso significa que solo puede subir al número 1. - Imprimir cadenas de formato como el tipo correcto. Afortunadamente, esto generalmente se detecta en tiempo de compilación, pero aún puede causar problemas. Asegúrese de que su carácter de formato
%{whatever}
se adapte a cualquier variable que desee poner en él.
Eso es todo lo que tengo por ahora. ¡Espero que mis miserias te hayan ahorrado algunos dolores de cabeza en el futuro! Si todo lo demás falla, ahora tengo una lista de cosas que revisar antes de arrancarme el cabello.