¿Qué es un fallo de segmentación?

9 minutos de lectura

¿Que es un fallo de segmentacion
Rajendra Uppal

¿Qué es un fallo de segmentación? ¿Es diferente en C y C++? ¿Cómo se relacionan las fallas de segmentación y los punteros colgantes?

  • ¡Solo un volcado de memoria cuando algo sale mal!

    – camino de resultados

    25 de abril de 2015 a las 1:18


  • Por lo general, se llama al intentar desreferenciar un puntero nulo, por lo que una falla de segmentación a menudo es análoga a una falla de Java. NullPointerException.

    – Raedwald

    18 de diciembre de 2017 a las 9:08


  • Segmentation viene de Segmentación de memoria. Estás accediendo a un segmento de la memoria que no te pertenece.

    – kotchwane

    13 de mayo de 2020 a las 10:33


1647639971 210 ¿Que es un fallo de segmentacion
zoul

La falla de segmentación es un tipo específico de error causado por el acceso a la memoria que “no le pertenece”. Es un mecanismo auxiliar que evita que se dañe la memoria y se introduzcan errores de memoria difíciles de depurar. Cada vez que obtiene una falla de segmentación, sabe que está haciendo algo mal con la memoria: acceder a una variable que ya se ha liberado, escribir en una parte de la memoria de solo lectura, etc. La falla de segmentación es esencialmente la misma en la mayoría de los lenguajes que le permiten desordenar con la gestión de la memoria, no existe una diferencia principal entre las fallas de segmento en C y C++.

Hay muchas formas de obtener un error de segmento, al menos en los lenguajes de nivel inferior como C(++). Una forma común de obtener un error de segmento es desreferenciar un puntero nulo:

int *p = NULL;
*p = 1;

Otro error de segmento ocurre cuando intenta escribir en una parte de la memoria que estaba marcada como de solo lectura:

char *str = "Foo"; // Compiler marks the constant string as read-only
*str="b"; // Which means this is illegal and results in a segfault

El puntero colgante apunta a algo que ya no existe, como aquí:

char *p = NULL;
{
    char c;
    p = &c;
}
// Now p is dangling

el puntero p cuelga porque apunta a la variable de carácter c que dejó de existir después de que terminó el bloque. Y cuando intenta desreferenciar el puntero colgante (como *p='A'), probablemente obtendrá un error de segmento.

  • El último ejemplo es particularmente desagradable, cuando construyo: int main() { char *p = 0; { char c = ‘x’; p = &c; } printf(“%c\n”,*p); devolver 0; } Con gcc o varios otros compiladores, ‘parece’ funcionar. No hay advertencias en la compilación. Sin defecto de privacidad. Esto se debe a que el ‘}’ fuera del alcance, en realidad no elimina los datos, solo los marca como libres para usarlos nuevamente. El código puede funcionar bien en un sistema de producción durante años, alteras otra parte del código, cambias el compilador o algo más y ¡BOOOOM!

    – Chris Huang-Leaver

    13 de abril de 2010 a las 9:06


  • Perdón por el golpe, pero solo una nota al margen … ninguno de sus ejemplos necesariamente causa una falla de segmento, de hecho, es solo un comportamiento indefinido 😉

    – obataku

    15 de septiembre de 2012 a las 3:01

  • @oldrinb: Es imposible escribir código que necesariamente provoca una falla de segmento. Sobre todo porque existen sistemas que funcionan sin protección de memoria, por lo que no pueden saber si una parte de la memoria realmente “pertenece a usted” y, por lo tanto, no sé segfaults, solo comportamiento indefinido… (clásico AmigaOS, por ejemplo)

    – DevSolar

    29 mayo 2014 a las 18:03


  • @ChrisHuang-Leaver, debes entender eso c es local, significa que se ha colocado en la pila después { y salió de él después }. el puntero colgante es solo una referencia a un desplazamiento que ahora está fuera de la pila. es por eso que modificarlo en un programa simple nunca activará ninguna falla de segmento. por otro lado, puede conducir a una falla de segmento en un caso de uso más complejo, donde otras llamadas a funciones pueden hacer que la pila crezca y contenga los datos a los que apunta el puntero colgante. escribir en esos datos (vars locales) conduciría a un comportamiento indefinido (segfault & Co)

    – Ayman Khamouma

    19 de enero de 2016 a las 21:23


  • @ ChrisHuang-Leaver, normalmente, cuando sale del alcance, el compilador tiene que recuperar algo de espacio de pila para liberar el espacio de pila no utilizado, pero esto no siempre sucede (siendo gcc uno de estos compiladores). Además, el espacio de pila asignado normalmente se reutiliza nuevamente, por lo que no he oído hablar de ningún sistema operativo que devuelva páginas de pila no utilizadas al sistema, lo que hace que ese espacio esté sujeto a un SIGSEGVpor lo que no esperaré tal señal al manipular la pila.

    – Luis Colorado

    22 de julio de 2016 a las 11:59

1647639972 951 ¿Que es un fallo de segmentacion
konrad.kruczynski

Vale la pena señalar que la falla de segmentación no se produce al acceder directamente a otra memoria de proceso (esto es lo que escucho a veces), ya que simplemente no es posible. Con la memoria virtual, cada proceso tiene su propio espacio de direcciones virtuales y no hay forma de acceder a otro usando cualquier valor de puntero. Una excepción a esto pueden ser las bibliotecas compartidas que son el mismo espacio de direcciones físicas asignadas a (posiblemente) diferentes direcciones virtuales y memoria del kernel que incluso se asigna de la misma manera en cada proceso (para evitar el vaciado de TLB en syscall, creo). Y cosas como shmat;) – esto es lo que considero acceso ‘indirecto’. Sin embargo, se puede verificar que generalmente se encuentran lejos del código del proceso y generalmente podemos acceder a ellos (es por eso que están allí, sin embargo, acceder a ellos de manera incorrecta producirá una falla de segmentación).

Aún así, la falla de segmentación puede ocurrir en caso de acceder a nuestra propia memoria (de proceso) de manera incorrecta (por ejemplo, al intentar escribir en un espacio no escribible). Pero la razón más común es el acceso a la parte del espacio de direcciones virtuales que es no mapeado a uno físico en absoluto.

Y todo ello con respecto a los sistemas de memoria virtual.

  • Con la memoria compartida/los archivos asignados a la memoria, es posible que otra persona se meta con su memoria. ¡En WIN32 también hay API desagradables como ‘WriteProcessMemory’!

    – Paula

    17 de febrero de 2014 a las 23:46

  • @paulm: Sí, lo sé. Esto es lo que tenía en mente en “Y cosas como shmat;) – esto es lo que considero acceso ‘indirecto'”.

    – konrad.kruczynski

    18 de febrero de 2014 a las 10:08

  • En un sistema operativo de memoria virtual no hay forma (normalmente, así que por favor, implementadores de sistemas operativos, no me llamen la atención por esto) para que un proceso acceda a otro proceso de memoria virtual, no siendo algún tipo de llamada al sistema de conexión de memoria que le permite acceso. Las direcciones de memoria virtual normalmente significan cosas diferentes según el proceso que se esté considerando.

    – Luis Colorado

    22 de julio de 2016 a las 12:02

Una falla de segmentación es causada por una solicitud de una página que el proceso no tiene en su tabla de descriptores, o una solicitud no válida para una página que sí tiene en la lista (por ejemplo, una solicitud de escritura en una página de solo lectura).

Un puntero colgante es un puntero que puede apuntar o no a una página válida, pero apunta a un segmento de memoria “inesperado”.

  • Esto es cierto, pero ¿realmente te ayudaría si no supieras qué es una falla de segmentación?

    – zoul

    27 de febrero de 2010 a las 9:37

Para ser honesto, como han mencionado otros carteles, Wikipedia tiene un artículo muy bueno sobre esto así que echa un vistazo allí. Este tipo de error es muy común y, a menudo, se denomina de otra manera, como violación de acceso o falla de protección general.

No son diferentes en C, C++ o cualquier otro lenguaje que permita punteros. Este tipo de errores generalmente son causados ​​por punteros que son

  1. Usado antes de ser correctamente inicializado
  2. Se utilizan después de que la memoria a la que apuntan se haya reasignado o eliminado.
  3. Se usa en una matriz indexada donde el índice está fuera de los límites de la matriz. Por lo general, esto es solo cuando está haciendo cálculos de puntero en matrices tradicionales o cadenas en C, no en colecciones basadas en STL/Boost (en C++).

¿Que es un fallo de segmentacion
Orhan Cinar

De acuerdo a Wikipedia:

Una falla de segmentación ocurre cuando un programa intenta acceder a una ubicación de memoria a la que no tiene permitido acceder, o intenta acceder a una ubicación de memoria de una manera que no está permitida (por ejemplo, intentando escribir en una ubicación de solo lectura, o para sobrescribir parte del sistema operativo).

Fallo de segmentación también es causado por fallas de hardware, en este caso las memorias RAM. Esta es la causa menos común, pero si no encuentra un error en su código, tal vez un memtest podría ayudarlo.

La solución en este caso, cambiar la RAM.

editar:

Aquí hay una referencia: Error de segmentación por hardware

1647639973 541 ¿Que es un fallo de segmentacion
Jamal

de Wikipedia Fallo de segmentación La página tiene una muy buena descripción al respecto, solo señalando las causas y razones. Eche un vistazo a la wiki para obtener una descripción detallada.

En informática, una falla de segmentación (a menudo abreviada como segfault) o violación de acceso es una falla provocada por el hardware con protección de memoria, que notifica a un sistema operativo (SO) sobre una violación de acceso a la memoria.

Las siguientes son algunas causas típicas de una falla de segmentación:

  • Desreferenciación de punteros NULL: este es un caso especial del hardware de administración de memoria
  • Intentar acceder a una dirección de memoria inexistente (espacio de direcciones del proceso externo)
  • Intentar acceder a la memoria para la que el programa no tiene derechos (como las estructuras del kernel en el contexto del proceso)
  • Intentar escribir memoria de solo lectura (como un segmento de código)

Estos, a su vez, a menudo son causados ​​​​por errores de programación que dan como resultado un acceso a la memoria no válido:

  • Eliminación de referencias o asignación a un puntero no inicializado (puntero salvaje, que apunta a una dirección de memoria aleatoria)

  • Desreferenciar o asignar a un puntero liberado (puntero colgante, que apunta a la memoria que se ha liberado/desasignado/eliminado)

  • Un desbordamiento de búfer.

  • Un desbordamiento de pila.

  • Intentar ejecutar un programa que no compila correctamente. (Algunos compiladores generarán un archivo ejecutable a pesar de la presencia de errores en tiempo de compilación).

¿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