2009-10-14 5 views
19

Necesito saber la causa raíz de la falla de segmentación, y también alguien me puede decir cómo manejarlo.¿Qué es el error de tiempo de ejecución SIGSEGV en C++?

+4

@GMan - La causa principal es probablemente una comprensión descuidada de los punteros. Sin decir nada sobre el OP, quizás no sea su código, simplemente que alguien no sabía cómo usar los punteros correctamente. –

+0

Más información sobre paginación: http://stackoverflow.com/questions/18431261/how-does-x86-paging-work –

Respuesta

37

Wikipedia tiene la respuesta, junto con una serie de otras fuentes.

Un segfault básicamente significa que hizo algo malo con los punteros. Esta es probablemente una violación de segmento:

char *c = NULL; 
... 
*c; // dereferencing a NULL pointer 

O esto:

char *c = "Hello"; 
... 
c[10] = 'z'; // out of bounds, or in this case, writing into read-only memory 

O tal vez esto:

char *c = new char[10]; 
... 
delete [] c; 
... 
c[2] = 'z'; // accessing freed memory 

mismo principio básico en cada caso - que está haciendo algo con memoria que ISN eres tuyo

3

usando un puntero nulo/nulo? ¿Desbordando los límites de una matriz? Kindof difícil de ser específico sin ningún código de muestra.

Esencialmente, está intentando acceder a la memoria que no pertenece a su programa, por lo que el sistema operativo lo mata.

4

Aquí hay un ejemplo de SIGSEGV.

[email protected]:/opt/playGround# cat test.c 
int main() 
{ 
    int * p ; 
    * p = 0x1234; 
    return 0 ; 
} 
[email protected]:/opt/playGround# g++ -o test test.c 
[email protected]:/opt/playGround# ./test 
Segmentation fault 

Y aquí está el detail.

¿Cómo solucionarlo?

  1. evitar en la medida de lo posible en el primer lugar.

    Programa de forma defensiva: use assert(), compruebe si el puntero es NULL, compruebe si hay desbordamiento del búfer.

    Utilice herramientas de análisis estáticas para examinar su código.

    compila tu código con -Werror -Wall.

    Alguien ha revisado su código.

  2. Cuando eso sucedió realmente.

    Examine su código cuidadosamente.

    Compruebe lo que ha cambiado desde la última vez que el código se ejecutó correctamente sin bloqueo.

    Afortunadamente, gdb le dará una pila de llamadas para que sepa dónde ocurrió el bloqueo.


Edit: Lo siento por un pico. Debería ser *p = 0x1234; en lugar de p = 0x1234;

+0

¿Por qué asignar un valor no válido a un puntero y no desreferenciar ese puntero SIGSEGV? – sharptooth

+1

Este programa no se compilará con ningún compilador C++. Si agrega el molde necesario, no se bloqueará, ya que en realidad no tiene ningún acceso de memoria no válido. –

+0

Estrictamente hablando, forzar un valor arbitrario en un objeto puntero puede hacer que un programa C/C++ se bloquee de inmediato, sin un intento de desreferencia (lea sobre "representaciones de trampas"), pero eso no es algo que la mayoría de nosotros podamos encontrar en práctica. Y, por supuesto, este no es un buen ejemplo para ilustrar SIGSEGV :) – AnT

11

Existen varias causas de fallas de segmentación, pero, fundamentalmente, está accediendo a la memoria incorrectamente.Esto podría deberse a la desreferenciación de un puntero nulo, o al intentar modificar la memoria de solo lectura, o al usar un puntero a un lugar que no está mapeado en el espacio de memoria de su proceso (eso probablemente significa que está tratando de usar un número como puntero) , o incrementó un puntero demasiado lejos). En algunas máquinas, es posible que un acceso desalineado a través de un puntero cause el problema también, si tiene una dirección impar e intente leer un número par de bytes, por ejemplo (que puede generar SIGBUS, en su lugar).

+0

Las diferentes señales de error aquí están mal definido - aquí en OS X, 'char * c = NULL; * c; 'en realidad genera un SIGBUS en lugar de un SIGSEGV. –

+0

Sí, tanto SIGBUS como SIGSEGV son algo específicos del sistema y/o del procesador. Ambos significan que estás abusando de la memoria. Ninguno de los dos es saludable. –

Cuestiones relacionadas