¿Qué es una falla de segmentación? ¿Es diferente en C y C ++? ¿Cómo se relacionan las fallas de segmentación y los punteros colgantes?
NullPointerException
.
¿Qué es una falla de segmentación? ¿Es diferente en C y C ++? ¿Cómo se relacionan las fallas de segmentación y los punteros colgantes?
NullPointerException
.
Respuestas:
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 corrompa la memoria e introduzca errores de memoria difíciles de depurar. Cada vez que obtienes un segfault, sabes que estás haciendo algo mal con la memoria: acceder a una variable que ya se ha liberado, escribir en una parte de solo lectura de la memoria, etc. La falla de segmentación es esencialmente la misma en la mayoría de los idiomas que te permiten jugar En la gestión de memoria, no existe una diferencia de principio entre los valores predeterminados en C y C ++.
Hay muchas formas de obtener una segfault, al menos en los lenguajes de nivel inferior como C (++). Una forma común de obtener un segfault es desreferenciar un puntero nulo:
int *p = NULL;
*p = 1;
Otro segfault ocurre cuando intenta escribir en una parte de la memoria que se marcó 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 señala una cosa 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 finalizó el bloque. Y cuando intente desreferenciar el puntero colgante (como *p='A'
), probablemente obtendrá un segfault.
c
es local, significa que se ha insertado en la pila después {
y ha salido de ella 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 desencadenará ningún defecto de seguridad. por otro lado, puede conducir a una falla predeterminada en un caso de uso más complejo, donde otras llamadas a funciones pueden hacer que la pila crezca y contenga los datos apuntados por el puntero colgante. escribir en esos datos (variables locales) conduciría a un comportamiento indefinido (segfault & Co)
SIGSEGV
esté sujeto a una , por lo que no esperaré que tal señal se estropee con la pila.
Vale la pena señalar que la falla de segmentación no es causada por 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 dirección virtual y no hay forma de acceder a otro utilizando ningún valor de puntero. La excepción a esto puede ser bibliotecas compartidas que son el mismo espacio de direcciones físicas mapeado a (posiblemente) diferentes direcciones virtuales y memoria del núcleo, que incluso se mapea de la misma manera en cada proceso (para evitar que TLB se vacíe en syscall, creo). Y cosas como shmat;): esto es lo que cuento como acceso 'indirecto'. Sin embargo, se puede verificar que generalmente están ubicados lejos del código de proceso y que generalmente podemos acceder a ellos (es por eso que están allí,
Aún así, puede producirse un fallo de segmentación en caso de acceder a nuestra propia memoria (de proceso) de manera incorrecta (por ejemplo, al intentar escribir en un espacio no grabable). Pero la razón más común para esto es el acceso a la parte del espacio de direcciones virtual que no está asignada a la física.
Y todo esto con respecto a los sistemas de memoria virtual.
Una falla de segmentación es causada por una solicitud de una página que el proceso no ha incluido en su tabla de descriptores, o una solicitud no válida para una página que sí ha incluido (por ejemplo, una solicitud de escritura en una página de solo lectura).
Un puntero colgante es un puntero que puede o no apuntar a una página válida, pero apunta a un segmento de memoria "inesperado".
Para ser honesto, como han mencionado otros carteles, Wikipedia tiene un muy buen artículo sobre esto, así que eche un vistazo allí. Este tipo de error es muy común y a menudo se denomina otras cosas como infracció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
De acuerdo con wikipedia:
Se produce un error de segmentación cuando un programa intenta acceder a una ubicación de memoria a la que no está permitido acceder, o intenta acceder a una ubicación de memoria de una manera que no está permitida (por ejemplo, al intentar escribir en una ubicación de solo lectura, o para sobrescribir parte del sistema operativo).
La falla de segmentación también es causada 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: fallo de segmentación por hardware
La falla de segmentación ocurre cuando un proceso (instancia en ejecución de un programa) intenta acceder a la dirección de memoria de solo lectura o al rango de memoria que está utilizando otro proceso o accede a la dirección de memoria inexistente (no válida). El problema de la referencia colgante (puntero) significa que intentar acceder a un objeto o variable cuyo contenido ya se ha eliminado de la memoria, por ejemplo:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
La página Segmentation_fault de Wikipedia tiene una muy buena descripción al respecto, solo señala las causas y razones. Echa un vistazo a la wiki para obtener una descripción detallada.
En informática, un fallo de segmentación (a menudo acortado a segfault) o una infracción de acceso es un fallo provocado por el hardware con protección de memoria, que notifica a un sistema operativo (SO) sobre una infracción de acceso a la memoria.
Las siguientes son algunas causas típicas de una falla de segmentación:
Estos a su vez a menudo son causados por errores de programación que resultan en un acceso no válido a la memoria:
Desreferenciar o asignar a un puntero no inicializado (puntero comodín, 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.
Intentando ejecutar un programa que no se compila correctamente. (Algunos compiladores generarán un archivo ejecutable a pesar de la presencia de errores en tiempo de compilación).
En palabras simples: falla de segmentación es el sistema operativo que envía una señal al programa diciendo que ha detectado un acceso ilegal a la memoria y está terminando prematuramente el programa para evitar que la memoria se corrompa.
"Falla de segmentación" significa que intentó acceder a la memoria a la que no tiene acceso.
El primer problema es con sus argumentos de main. La función principal debe ser int main(int argc, char *argv[])
, y debe comprobar que argc es al menos 2 antes de acceder a argv [1].
Además, dado que está pasando un flotante a printf (que, por cierto, se convierte en un doble al pasar a printf), debe usar el especificador de formato% f. El especificador de formato% s es para cadenas (matrices de caracteres con terminación '\ 0').
Se produce un error de segmentación o una infracción de acceso cuando un programa intenta acceder a una ubicación de memoria que no existe, o intenta acceder a una ubicación de memoria de una manera que no está permitida.
/* "Array out of bounds" error
valid indices for array foo
are 0, 1, ... 999 */
int foo[1000];
for (int i = 0; i <= 1000 ; i++)
foo[i] = i;
Aquí i [1000] no existe, por lo que se produce una falla predeterminada.
Causas de la falla de segmentación:
it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.
De-referencing NULL pointers – this is special-cased by memory management hardware.
Attempting to access a nonexistent memory address (outside process’s address space).
Attempting to access memory the program does not have rights to (such as kernel structures in process context).
Attempting to write read-only memory (such as code segment).
Hay varias buenas explicaciones de "Fallo de segmentación" en las respuestas, pero dado que con el fallo de segmentación a menudo hay un volcado del contenido de la memoria, quería compartir dónde está la relación entre la parte "volcado de núcleo" en Fallo de segmentación (núcleo volcado) y la memoria proviene de:
Desde aproximadamente 1955 hasta 1975, antes de la memoria de semiconductores, la tecnología dominante en la memoria de la computadora utilizaba pequeñas donas magnéticas colgadas de cables de cobre. Las rosquillas se conocían como "núcleos de ferrita" y la memoria principal, así conocida como "memoria central" o "núcleo".
Tomado de aquí .
Hay suficientes definiciones de falla de segmentación, me gustaría citar algunos ejemplos que encontré durante la programación, que pueden parecer errores tontos, pero perderán mucho tiempo.
puede obtener una falla de segmentación en el siguiente caso, mientras que el tipo de argumento no coincide en printf
#include<stdio.h>
int main(){
int a = 5;
printf("%s",a);
return 0;
}
salida: Segmentation Fault (SIGSEGV)
cuando olvidaste asignar memoria a un puntero, pero intentaste usarlo.
#include<stdio.h>
typedef struct{
int a;
}myStruct;
int main(){
myStruct *s;
/* few lines of code */
s->a = 5;
return 0;
}
salida: Segmentation Fault (SIGSEGV)
El significado simple de Segmentation fault
es que está intentando acceder a alguna memoria que no le pertenece. Segmentation fault
ocurre cuando intentamos leer y / o escribir tareas en una ubicación de memoria de solo lectura o intentamos liberar memoria. En otras palabras, podemos explicar esto como algún tipo de corrupción de memoria.
A continuación menciono los errores comunes cometidos por los programadores que conducen a Segmentation fault
.
scanf()
de manera incorrecta (olvidé poner &
).int num;
scanf("%d", num);// must use &num instead of num
int *num;
printf("%d",*num); //*num should be correct as num only
//Unless You can use *num but you have to point this pointer to valid memory address before accessing it.
char *str;
//Stored in read only part of data segment
str = "GfG";
//Problem: trying to modify read only memory
*(str+1) = 'n';
// allocating memory to num
int* num = malloc(8);
*num = 100;
// de-allocated the space allocated to num
free(num);
// num is already freed there for it cause segmentation fault
*num = 110;
printf()
y scanf()
'