O que é uma falha de segmentação? É diferente em C e C ++? Como as falhas de segmentação e os ponteiros oscilantes estão relacionados?
NullPointerException
.
O que é uma falha de segmentação? É diferente em C e C ++? Como as falhas de segmentação e os ponteiros oscilantes estão relacionados?
NullPointerException
.
Respostas:
A falha de segmentação é um tipo específico de erro causado pelo acesso à memória que "não pertence a você". É um mecanismo auxiliar que evita que você corrompa a memória e introduza erros de memória difíceis de depurar. Sempre que você obtém um segfault, sabe que está fazendo algo errado com a memória - acessando a variável que já foi liberada, gravando em uma parte somente leitura da memória, etc. A falha de segmentação é essencialmente a mesma na maioria dos idiomas que permitem mexer com No gerenciamento de memória, não há diferença principial entre segfaults em C e C ++.
Existem várias maneiras de obter um segfault, pelo menos nos idiomas de nível inferior, como C (++). Uma maneira comum de obter um segfault é desreferenciar um ponteiro nulo:
int *p = NULL;
*p = 1;
Outro segfault acontece quando você tenta gravar em uma parte da memória que foi marcada como somente leitura:
char *str = "Foo"; // Compiler marks the constant string as read-only
*str = 'b'; // Which means this is illegal and results in a segfault
O ponteiro oscilante aponta para algo que não existe mais, como aqui:
char *p = NULL;
{
char c;
p = &c;
}
// Now p is dangling
O ponteiro p
oscila porque aponta para a variável de caractere c
que deixou de existir após o término do bloco. E quando você tenta desreferenciar o ponteiro oscilante (como *p='A'
), provavelmente obterá um segfault.
c
é local, significa que ele foi empurrado para a pilha depois {
e retirado dela depois }
. o ponteiro pendente é apenas uma referência a um deslocamento que agora está fora da pilha. é por isso que modificá-lo em um programa simples nunca disparará nenhum segfault. por outro lado, isso pode levar ao segfault em um caso de uso mais complexo, onde outras chamadas de função podem levar a pilha a crescer e conter os dados apontados pelo ponteiro pendente. escrevendo para que os dados (VARs locais) levaria a um comportamento indefinido (segfault & Co)
SIGSEGV
, para que eu não espere que esse sinal seja confundido com a pilha.
Vale a pena notar que a falha de segmentação não é causada pelo acesso direto a outra memória do processo (é isso que estou ouvindo às vezes), pois simplesmente não é possível. Com a memória virtual, todo processo tem seu próprio espaço de endereço virtual e não há como acessar outro usando qualquer valor de ponteiro. A exceção a isso pode ser bibliotecas compartilhadas, que são o mesmo espaço de endereço físico mapeado para (possivelmente) diferentes endereços virtuais e memória do kernel, que é mapeada da mesma maneira em todos os processos (para evitar a liberação de TLB no syscall, eu acho). E coisas como shmat;) - são o que eu considero como acesso "indireto". No entanto, é possível verificar se eles estão localizados muito longe do código do processo e que geralmente podemos acessá-los (é por isso que eles estão lá,
Ainda assim, uma falha de segmentação pode ocorrer no caso de acessar nossa própria memória (processo) de maneira inadequada (por exemplo, tentando gravar em espaço não gravável). Mas o motivo mais comum para isso é o acesso à parte do espaço de endereço virtual que não é mapeado para o físico.
E tudo isso com relação aos sistemas de memória virtual.
Uma falha de segmentação é causada por uma solicitação de uma página que o processo não listou em sua tabela de descritores ou uma solicitação inválida para uma página que listou (por exemplo, uma solicitação de gravação em uma página somente leitura).
Um ponteiro danificado é um ponteiro que pode ou não apontar para uma página válida, mas aponta para um segmento "inesperado" da memória.
Para ser honesto, como outros pôsteres mencionaram, a Wikipedia tem um artigo muito bom sobre isso, então dê uma olhada lá. Esse tipo de erro é muito comum e costuma ser chamado de outras coisas, como violação de acesso ou falha de proteção geral.
Eles não são diferentes em C, C ++ ou qualquer outra linguagem que permita ponteiros. Esses tipos de erros geralmente são causados por ponteiros que são
De acordo com a wikipedia:
Uma falha de segmentação ocorre quando um programa tenta acessar um local de memória que não tem permissão para acessar ou tenta acessar um local de memória de uma maneira que não é permitida (por exemplo, tentando gravar em um local somente leitura, ou substituir parte do sistema operacional).
A falha de segmentação também é causada por falhas de hardware, neste caso, as memórias de RAM. Essa é a causa menos comum, mas se você não encontrar um erro no seu código, talvez um teste de memória possa ajudá-lo.
A solução neste caso, altere a RAM.
editar:
Aqui está uma referência: Falha na segmentação por hardware
A falha de segmentação ocorre quando um processo (executando uma instância de um programa) está tentando acessar o endereço de memória somente leitura ou o intervalo de memória que está sendo usado por outro processo ou acessar o endereço de memória inexistente (inválido). Problema de referência de oscilação (ponteiro) significa que tentar acessar um objeto ou variável cujo conteúdo já foi excluído da memória, por exemplo:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
A página Segmentation_fault da Wikipedia tem uma descrição muito boa, apenas apontando as causas e razões. Dê uma olhada no wiki para uma descrição detalhada.
Na computação, uma falha de segmentação (geralmente abreviada para segfault) ou violação de acesso é uma falha provocada por hardware com proteção de memória, notificando um sistema operacional sobre uma violação de acesso à memória.
A seguir, algumas causas típicas de uma falha de segmentação:
Por sua vez, geralmente são causados por erros de programação que resultam em acesso inválido à memória:
Desreferenciando ou atribuindo a um ponteiro não inicializado (ponteiro curinga, que aponta para um endereço de memória aleatório)
Desreferenciando ou atribuindo a um ponteiro liberado (ponteiro pendente, que aponta para a memória que foi liberada / desalocada / excluída)
Um estouro de buffer.
Um estouro de pilha.
Tentativa de executar um programa que não é compilado corretamente. (Alguns compiladores produzirão um arquivo executável, apesar da presença de erros em tempo de compilação.)
Em palavras simples: falha de segmentação é o sistema operacional que envia um sinal ao programa dizendo que detectou um acesso ilegal à memória e está encerrando prematuramente o programa para evitar que a memória seja corrompida.
"Falha na segmentação" significa que você tentou acessar a memória à qual não tem acesso.
O primeiro problema é com seus argumentos de main. A função principal deve ser int main(int argc, char *argv[])
, e você deve verificar se argc é pelo menos 2 antes de acessar o argv [1].
Além disso, como você está passando um float para printf (que, a propósito, é convertido em um duplo ao passar para printf), você deve usar o especificador de formato% f. O especificador de formato% s é para seqüências de caracteres (matrizes de caracteres terminados em '\ 0').
Uma falha de segmentação ou violação de acesso ocorre quando um programa tenta acessar um local de memória que não existe ou tenta acessar um local de memória de uma maneira que não é 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;
Aqui eu [1000] não existe, então ocorre o segfault.
Causas de falha de segmentação:
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).
Existem várias boas explicações sobre "Falha de segmentação" nas respostas, mas como na falha de segmentação geralmente há um despejo do conteúdo da memória, eu queria compartilhar onde a relação entre o "núcleo despejado" parte da parte de Falha de segmentação (núcleo despejado) e a memória vem de:
Entre 1955 e 1975 - antes da memória de semicondutores - a tecnologia dominante na memória de computadores usava pequenas rosquinhas magnéticas amarradas em fios de cobre. Os donuts eram conhecidos como "núcleos de ferrite" e a memória principal, conhecida como "memória de núcleo" ou "núcleo".
Retirado daqui .
Existem definições suficientes de falha de segmentação. Gostaria de citar alguns exemplos que encontrei durante a programação, que podem parecer erros tolos, mas que desperdiçam muito tempo.
você pode obter uma falha de segmentação no caso abaixo, enquanto a incompatibilidade do tipo argumet no printf
#include<stdio.h>
int main(){
int a = 5;
printf("%s",a);
return 0;
}
resultado : Segmentation Fault (SIGSEGV)
quando você esqueceu de alocar memória para um ponteiro, mas tentando usá-lo.
#include<stdio.h>
typedef struct{
int a;
}myStruct;
int main(){
myStruct *s;
/* few lines of code */
s->a = 5;
return 0;
}
resultado : Segmentation Fault (SIGSEGV)
O significado simples de Segmentation fault
é que você está tentando acessar alguma memória que não lhe pertence. Segmentation fault
ocorre quando tentamos ler e / ou gravar tarefas em um local de memória somente leitura ou tentamos liberar memória. Em outras palavras, podemos explicar isso como algum tipo de corrupção de memória.
Abaixo menciono erros comuns cometidos por programadores que levam a Segmentation fault
.
scanf()
maneira errada (esqueceu de colocar &
).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()
e scanf()
'