View Full Version : [Sistemi operativi & C]chi mi spiega questa cosa?
The Incredible
30-04-2007, 13:39
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigsegv_handler(int sig) {
printf("Ricevuta una signal di segmentation fault (SIGSEGV).\n");
exit(0);
}
int main() {
int *null_pointer=(int *)NULL;
signal(SIGSEGV,sigsegv_handler);
printf("Che succede qui di seguito?\n");
*null_pointer=0;
printf("Perche’ non viene stampata questa riga?\n");
return 1;
}
non riesco a capire cosa fà il null_pointer e come mai blocca l'ultima printf.
Qlc è in grado di spigarmelo?
Grazie
The Incredible
30-04-2007, 13:42
quello che posso aver capito io è che essendo la variabile un puntatore ad interi, invece di passargli un puntatore gli passo un numero e quindi và in errore(segmentation).. può essere ?
The Incredible
30-04-2007, 13:44
a riprova di quello che ho detto:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigsegv_handler(int sig) {
printf("Ricevuta una signal di segmentation fault (SIGSEGV).\n");
exit(0);
}
int main() {
//int *null_pointer=(int *)NULL;
int null_pointer;
signal(SIGSEGV,sigsegv_handler);
printf("Che succede qui di seguito?\n");
null_pointer=0;
printf("Perche’ non viene stampata questa riga?\n");
return 1;
}
quindi dovrebbe essere giusta la mia affermazione.:)
il problema è che inizializzi quel puntatore al valore NULL, poi tenti di accedere all'area di memoria con indirizzo NULL e ovviamente hai un errore.
per farlo funzionare basterebbe qualcosa tipo
int a;
int *pointer;
pointer = &a; // &a vuol dire indirizzo della variabile a
*pointer = 10;
così funziona, perché a pointer assegni un indirizzo valido
Se non ricordo male la mie antiche conoscenze di C, tu con
int *null_pointer=(int *)NULL;
crei un puntatore ad interi che punta all'indirizzo 0x0 della memoria (indirizzo non valido per eccellenza) e poi cerchi di riempire quella prima cella con un intero:
*null_pointer=0;
cosa che provoca appunto un segmentation fault o un gpe.
Infatti, mi pare che *null_pointer usato in sede di definizione/dichiarazione cioè in
int *null_pointer=(int *)NULL;
accetti come rvalue un indirizzo (infatti facendo il casting (int*) non ti da errori o warning),
mentre *nullpointer usato in altri contesti come ad esempio in:
*null_pointer=0;
accetti come rvalue il valore del dato referenziato (in questo caso un intero).
Poi magari mi ricordo male ed ho detto una cavolata, quindi controlla, se puoi, in qualche manuale.
Ciao
Ha ragione recoil...
Infatti il puntatore null_pointer è inzializzato a NULL (cioè 0), se faccio *null_pointer = 0; voglio andare a scrivere nella memoria all'indirizzo NULL il valore 0...e non è possibile ;)
sottovento
01-05-2007, 04:41
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigsegv_handler(int sig) {
printf("Ricevuta una signal di segmentation fault (SIGSEGV).\n");
exit(0);
}
int main() {
int *null_pointer=(int *)NULL;
signal(SIGSEGV,sigsegv_handler);
printf("Che succede qui di seguito?\n");
*null_pointer=0;
printf("Perche’ non viene stampata questa riga?\n");
return 1;
}
non riesco a capire cosa fà il null_pointer e come mai blocca l'ultima printf.
Qlc è in grado di spigarmelo?
Grazie
Le spiegazioni date sono tutte corrette. Volevo solo aggiungere questo.
Il programma in questione serve per mostrare come si catturano i segnali in C.
Come gia' spiegato, viene creato un puntatore all'indirizzo 0, il quale e' un indirizzo invalido.
Dopo di che si esegue la signal(), la quale significa: "In caso di errori quali, per esempio, il segmentation error, dovrai eseguire la funzione il cui nome e' sigsegv_handler". Puoi ben immaginare come questo sia molto utile in applicazioni molto complesse, per recuperare la situazione in caso di errori gravi.
A questo punto, per dimostrare che effettivamente funziona, viene causato l'errore in questione: hai il puntatore all'indirizzo nullo e quindi provi a scriverci.
(i.e. *null_pointer=0; )
Come conseguenza di questo, l'esecuzione del tuo programma normale viene interrotta (i.e. non vedi la "Perche’ non viene stampata questa riga?") e viene eseguita la "procedura di emergenza", la quale andra' a scrivere "Ricevuta una signal di segmentation fault (SIGSEGV)."
DIMENTICAVO: un giorno scriverai (o lo stai gia' scrivendo) un programma molto grosso ed articolato in C++ e vorrai utilizzare anche queste funzioni per catturare dei segnali di tuo interesse.
Fai attenzione ad una cosa: la semantica del C++ e quella del C non sempre sono compatibili! Sembra stranissimo (tutti infatti dicono che il C++ e' un sovrainsieme del C) ma e' cosi'!
L'utilizzo di queste funzionalita' tipiche del C in un programma C++ puo' portare a comportamenti davvero strani, quali la mancata gestione delle eccezioni C++, costruttori non chiamati ed altre stranezze simili!
cosa che provoca appunto un segmentation fault o un gpe. non è GPE :Prrr:
inizialmente è un page fault, poi il sistema si accorge che il PF è causato non dal fatto che la pagina è stata swappata, ma dal fatto che non è stata manco allocata, e allora reagisce coi meccanismi suoi (signal handlers, SEH, <metti qui il tuo meccanismo preferito> ) :read:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.