Tengo una aplicación Linux C++ y me gustaría probar la validez de un puntero a un objeto antes de desreferenciarlo. Sin embargo, try/catch no funciona para esto en Linux debido a la falla de segmentación. ¿Cómo puede hacerse esto?Intente/Capture un error de segmentación en Linux
Respuesta
Si tiene un escenario donde muchos punteros en su aplicación hacen referencia a los mismos objetos de vida útil limitada, una solución popular es usar boost smart pointers. Editar: en C++ 11, ambos de estos tipos están disponibles en la biblioteca estándar
Usted desea utilizar shared_ptr
de puntero (s) que son responsables de la vida de su objeto y weak_ptr
para los otros punteros , que puede convertirse en inválido. Verá que weak_ptr
tiene la verificación de validez que está solicitando.
Inicialice su puntero a NULL. Si después de algún procesamiento sigue siendo NULL, no es válido; de lo contrario, es válido.
Si elimino un objeto que es el puntero no es NULO, pero apunta a la memoria no válida. ¿Cómo puedo validar ese puntero? – jackhab
¿Por qué diablos querrías? Lo borraste Si está utilizando punteros en cualquier lugar y no está seguro de si están eliminados o no, está haciendo algo MUY incorrecto. – Bombe
Yo en segundo lugar. Los punteros inválidos son punteros no válidos. Luego, ya no se puede acceder a la variable de puntero, o la configura en 0. O, como esto es C++, aprenda acerca de RAII. – gimpf
Puede habilitar un manejador de señal para SIGSEGV para esta ocasión. Vea la "señal" de la página del manual para más detalles. La otra alternativa es usar referencias que garanticen ser válidas. Depende de tu aplicación, por supuesto.
La página man dice que el estado del proceso no está definido si ignora el SIGSEGV. ¿Puedo reanudar la aplicación C++ después de atrapar SIGSEGV? – jackhab
Buena pregunta, probablemente no de manera segura. Creo que, en general, es mejor usar referencias en lugar de punteros si te preocupa la validez. Como han señalado los otros carteles, puede iniciar sesión donde ocurre el error y corregirlo. –
No se garantiza que las referencias sean válidas. Si la duración del objeto al que se hace referencia finaliza antes de que se utilice la referencia, los resultados tampoco están definidos (en la práctica, son idénticos a un puntero no válido). Las referencias no se pueden inicializar a nulo y no a restablecer. Eso es. – gimpf
Un error de segmentación no es una excepción (como la NullPointerException de Java); es una señal enviada desde el SO al proceso. Eche un vistazo a the manpage for sigaction para ver los consejos sobre cómo instalar un controlador para el error de segmentación (SIGSEGV).
¿Cómo se prueba la validez del puntero? Comparar con NULL?
Lo mejor que puede hacer es ejecutar su programa bajo Valgrind. Un error puede estar en un lugar bastante diferente.
Actualización: en la plataforma Win32 hay algo así como __try __except que permite detectar algunas excepciones. Hasta donde sé, no hay un equivalente de Linux para esa función de Win32.
En Windows puedes ver una excepción cuando accedes a un puntero para desasignar objetos y puedes manejar la situación. En Linux obtienes SIGSEGV. Mi pregunta es si hay alguna forma de validar un puntero que una vez apuntó a un objeto y por lo tanto no es NULL pero aún invalidado por el operador de eliminación. – jackhab
No soy experto en Win32 pero una vez que utilicé __try __ excepto por tales cosas. –
Esas cosas solo para Windows, exponiendo la "Excepción estructurada" de la plataforma manejo "(SEH) en C++. El equivalente de Linux es señales ... pero creo que la sugerencia de Shmoopty de shared_ptr/weak_ptr está más en la línea correcta. – timday
Si adjunta un controlador al SIGSEGV, no hay mucho que pueda hacer además de registrar el hecho de que el error ocurrió y fallar correctamente. Su programa se encuentra en un estado indefinido cuando ocurre esta infracción y, por lo tanto, puede no ser seguro continuar con la operación normal.
Más allá de buscar NULL No creo que haya una manera de comprobar si un puntero es "válido" en el sentido que está describiendo. Durante la operación normal, errores como este no deberían ocurrir, ya que representan un error, por lo que debería querer que su programa falle, aunque con gracia.
Los punteros se almacenan en objetos. Se inicializan en el constructor, potencialmente a 0 (NULO). Se eliminan en el destructor, posiblemente en la asignación y rara vez en otras funciones. Cuando se eliminan en miembros que no sean el destructor, se les asigna inmediatamente un nuevo valor o 0.
No existe una forma natural y universal con los punteros sin formato de C++. C++ supone que hará un seguimiento de esa información.
En la mayoría de las situaciones, puede manejar esto recordando establecer punteros a NULL cuando no son válidos. Los nuevos punteros que inicialmente no apuntan deben establecerse en NULL y los objetos recién eliminados deben tener sus punteros establecidos en NULL.
En general, con respecto a la idea bastante extraña de "comprobación de un puntero no nulo para la validez", echar un vistazo a este artículo: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx ("IsBadXxxPtr debería llamarse en realidad CrashProgramRandomly")
- 1. Error de segmentación de Java
- 2. Error de segmentación en PHP?
- 3. Nokogiri ¿Error de segmentación?
- 4. Error de segmentación: cómo.
- 5. MPI Error de segmentación en MPI_Isend()
- 6. python rastreando un error de segmentación
- 7. Error de bus vs Error de segmentación
- 8. Error de segmentación (núcleo volcado)
- 9. Error de segmentación, matrices grandes
- 10. Error de segmentación en libcurl, multiproceso
- 11. Código de auto modificación siempre fallas de segmentación en Linux
- 12. Error de segmentación en malloc_consolidate (malloc.c) que valgrind no detecta
- 13. Nmap :: Analizador, Error de segmentación en archivos grandes
- 14. Error de segmentación causado por pthread_kill
- 15. NSNotificación lleva al error de segmentación
- 16. Puntero C para Struct - Error de segmentación
- 17. Error de segmentación con OpenMp y SSE
- 18. Cómo solucionar el "error de segmentación [BUG]"?
- 19. ¿Por qué lo siguiente producirá un error de segmentación?
- 20. arrojando una excepción provoca un error de segmentación
- 21. Un simple programa de memoria compartida en C++ escrito en Linux: falla de segmentación
- 22. cómo hacer que eclipse cdt muestre un error de tiempo de ejecución (por ejemplo, un error de segmentación)
- 23. Error de segmentación en tamaños de matriz grande
- 24. ¿Cuál es SIGSEGV, error de segmentación en Qt
- 25. Error de segmentación al intentar imprimir el valor en C
- 26. Error de segmentación al asignar grandes matrices en la pila
- 27. Error de segmentación al utilizar dlclose (...) en la plataforma Android
- 28. "Error de segmentación" durante "importar cv" en Mac OS
- 29. Error de segmentación de script de rieles con RVM
- 30. Segmentación de memoria en sistemas operativos modernos
No he usado shared_prt, pero por lo que tengo entendido, es un puntero que controla el tiempo de vida del objeto. Tengo una situación opuesta. Tengo un objeto que puede eliminarse al recibir un mensaje. Necesito que aquellos que lo señalan tengan una manera de saber que poseen s puntero no válido – jackhab
Ese es exactamente el tipo de caso para el que está hecho weak_ptr. El weak_ptr dejará que el objeto muera e informará la invalidez si luego intenta acceder al objeto a través del weak_ptr. ¡Una solución mucho mejor que atrapar SIGSEGV! – timday
Eso es lo que pensé que era tu situación. El mensaje "eliminarme" debería restablecer el shared_ptr único. Después de eso, todos los weak_ptr's hechos de ese shared_ptr sabrán que son inválidos. Echa un vistazo al enlace weak_ptr para ver ejemplos. –