Newsgroup: it.comp.lang.c++
Titolo: stranezze...

ho il seguente codice che non capisco perchè in un caso segfaulta e
nell'altro no:
#include <iostream>
int main()
{
  double* test;
  *test=44;
  std::cout << *test << "\n";
  //int i =0
};
se compilato(con g++) cosi va in fault alla riga:
*test=44;
se decommentate
//int i =0
stampa 44; perchè nel primo caso faulta e nel secondo no??? posso
immaginare sia qualche ottimizziaone fatta dal compilatore ma non
saprei proprio.
ancora una cosa: se compilo con gcc (C quindi), sostituendo std::cout
con printf("%d", *test); faulta sempre a seconda che la dichiarazione
di i sia commentata o no, però stampa 0 al posto di 44; che differenze
ci sono in questo caso tra C++ e C?
Grazie mille!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 };
Il puntatore test ha un valore indefinito e quindi il codice che hai
scritto è "sbagliato", perché stai scrivendo 44 in una locazione di
memoria a caso (probabilmente all'indirizzo 0).
Non so perché se aggiungi la riga commentata non ti dia "segmentation
fault", ma non capisco perché lo vorresti sapere.
E.

 fault", ma non capisco perché lo vorresti sapere.
perchè è un comportamento anomalo, almeno per me, e volveo capire il
perchè di questo risultato.
Ciao

 perchè di questo risultato.
Non è anomalo. L'imprevedibilità del risultato è esattamente ciò che significa 
"undefined behavior".
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 
è normale che dichiarando una variabile dopo quell'erroraccio il
programma non segfaulti ??
Ciao

 programma non segfaulti ??
Sì. Il tuo programma non ha un comportamento definito e quindi può dare 
qualsiasi risultato e questo risultato può cambiare in maniera imprevedibile 
dall'apparente perfetto funzionamento al segfault (una volta si diceva che 
poteva anche farti uscire i mostriciattoli verdi dal naso, o qualcosa del 
genere :-).


 stampa 44; perchè nel primo caso faulta e nel secondo no??? 
Per la cronaca: sul mio computer
	g++ (GCC) 3.3.5 (Debian 1:3.3.5-13)
la prima versione non faulta. Fatti stampare il valore del puntatore per
vedere se cambia nei due casi.
E.

 dal naso, o qualcosa del genere :-).
ok capito! però mi sa di strano lo stesso :) facendo ++(*test) ritorna
45 (sempre che ci sia i dichiarata ovviamente).
va bho, misteri dei compilatori e dei comportamenti indefiniti :)
Ciao

 programma non segfaulti ??
Ma secondo te cosa significa "segmentation fault" (o "Access
Violation", per chi lavora sotto Windows)?
Ciao,
Nicola

 va bho, misteri dei compilatori e dei comportamenti indefiniti :)
Il comportamenti indefiniti sono conseguenza di istruzioni sbagliate.


Fermo restando quello che ti han detto gli altri, la cosa che
_probabilmente_ succede (ma che potrebbe anche cambiare,
anche solo ricompilandolo una seconda volta) è che alla riga
*test=44;
vai a scrivere nella locazione di memoria che il compilatore ha
riservato per l'int e che nell'altro caso non hai.
Comunque concordo con gli altri che la tua domanda ha come
unica risposta la definizione di "undefined behavior"
-- 
Gerolamo 

saprei proprio.
Col g++ prova a compilare questo:
int main ()
{
double *test;
double i = 0;
*test = 44;
std::cout << *test << "\n";
std::cout << i << "\n";
};
se stampa:
44
44
siamo sulla buona strada. ;)

 ci sono in questo caso tra C++ e C?
Il problema e' che quanso si usa in modo errato l'accesso alla memoria
tramite puntatori, quello che accade e' "imprevedibile" e "imprevedibile"
significa appunto che talvolta (io direi "piu' spesso di quanto
non si creda") il sistema puo' funzionare normalmente, mentre altre volte
va tutto in crash (infatti vai ad alterare in modo del tutto casuale
i contenuti della memoria del tuo computer): non mi stupirebbe affatto che
il tuo programmino
funzionasse per un mese ininterrottamente e poi, improvvisamente,
cominiciasse ad andare in crash ogni volta che lo lanci 
(mi e' capitato, lavorativamente parlando, di avere a che fare
con sistemi che si comportavano come sopra descritto)
Ciao,
Marco.

 ci sono in questo caso tra C++ e C?
Che %d si usa per stampare interi decimali.
Ciao,
Nicola

 indirizzo.
Questo mi sembra verificabile facilmente con un debugger. Se lui ne ha a
disposizione uno puo' provare.
In particolare ho provato con il gdb di cygwin su windows XP
 #include <iostream>
 int main()
 {
   double* test;
   *test=44;
   std::cout << *test << "\n";
   //int i =0
 };
Administrator@NOTEBOOKMGHP ~/c++
$ g++ -g -Wall main.cc   -o main
Administrator@NOTEBOOKMGHP ~/c++
$ gdb main
GNU gdb 6.5.50.20060706-cvs (cygwin-special)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
(gdb) l
1        #include <iostream>
2
3        int main()
4        {
5          double* test;
6          *test=44;
7          std::cout << *test << "\n";
8          //int i =0
9
10       };
(gdb) b main
Breakpoint 1 at 0x401175: file main.cc, line 4.
(gdb) run
Starting program: /home/Administrator/c++/main.exe
Loaded symbols for /cygdrive/c/WINDOWS/system32/ntdll.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/kernel32.dll
Loaded symbols for /usr/bin/cygwin1.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/advapi32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/rpcrt4.dll
Breakpoint 1, main () at main.cc:4
4        {
(gdb) n
6          *test=44;
(gdb) p test
$1 = (double *) 0x410960
(gdb) p &test
$2 = (double **) 0x23cca4
(gdb) p sizeof(44)
$3 = 4
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00401183 in main () at main.cc:6
6          *test=44;
(gdb)
come si vede in questo caso pare che test non contenga
l'indirizzo di test.
Comunque, che io mi ricordi non e' affatto garantito che
una variabile locale venga inizializzata con il proprio
indirizzo (e questo mi sembrerebbe comunque avere senso solo per
i puntatori; per altri tipi mi sembrerebbe perlomeno strano).
A me comunque, anche togliendo il commento continua a dare errore
(le locazioni di memoria non cambiano e il compilatore pare
accorgersi che i e' inutilizzata => forse non le riserva nemmeno
memoria)
Administrator@NOTEBOOKMGHP ~/c++
$ !g++
g++ -g -Wall main.cc   -o main
main.cc: In function `int main()':
main.cc:8: warning: unused variable 'i'
Administrator@NOTEBOOKMGHP ~/c++
$ gdb main
GNU gdb 6.5.50.20060706-cvs (cygwin-special)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
(gdb) b main
Breakpoint 1 at 0x401175: file main.cc, line 4.
(gdb) run
Starting program: /home/Administrator/c++/main.exe
Loaded symbols for /cygdrive/c/WINDOWS/system32/ntdll.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/kernel32.dll
Loaded symbols for /usr/bin/cygwin1.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/advapi32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/rpcrt4.dll
Breakpoint 1, main () at main.cc:4
4        {
(gdb) n
6          *test=44;
(gdb) p test
$1 = (double *) 0x410960
(gdb) p &test
$2 = (double **) 0x23cca4
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00401183 in main () at main.cc:6
6          *test=44;
(gdb)
Ho provato ad aggiungere una linea di codice per vedere
se cambiava qualcosa, come segue
 #include <iostream>
 int main(int argc, char *argv[])
 {
   double* test;
   *test=44;
   std::cout << *test << "\n";
   int i =0;
   if(argc != 1) i=argc;
   std::cout << i <<std::endl;
 };
ma in realta', anche se il contenuto iniziale di test cambia
(ma non il suo indirizzo), il programma mi va ancora in crash
Administrator@NOTEBOOKMGHP ~/c++
$ !g+
g++ -g -Wall main.cc   -o main
Administrator@NOTEBOOKMGHP ~/c++
$ !gdb
gdb main
GNU gdb 6.5.50.20060706-cvs (cygwin-special)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
(gdb) b main
Breakpoint 1 at 0x401175: file main.cc, line 4.
(gdb) run
Starting program: /home/Administrator/c++/main.exe
Loaded symbols for /cygdrive/c/WINDOWS/system32/ntdll.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/kernel32.dll
Loaded symbols for /usr/bin/cygwin1.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/advapi32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/rpcrt4.dll
Breakpoint 1, main (argc=1, argv=0x6c2a10) at main.cc:4
4        {
(gdb) n
6          *test=44;
(gdb) p test
$1 = (double *) 0x410990
(gdb) p &test
$2 = (double **) 0x23cca4
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00401183 in main (argc=1, argv=0x6c2a10) at main.cc:6
6          *test=44;
(gdb)
Ciao,
Marco.

 i puntatori; per altri tipi mi sembrerebbe perlomeno strano).
Certamente. La mia ipotesi non era tanto che la variabile fosse
inizializzata col proprio indirizzo, cosa che non mi aspetterei,
quanto essendo allocata sullo stack si ritrovava il proprio indirizzo
per un uso precedente della stessa locazione. A pensarci bene anche
questo non e' molto sensato, perche' non si vede lo scopo di salvarsi
la posizione corrente sullo stack.
In realta' volevo solo far capire all'OP che quello che lui osserva
non succede per caso, ma e' il risultato dell'operato del compilatore
combinato col contenuto della memoria non inizializzata. Questo non e'
casuale, anche se lo sembra; dipende dai precedenti utilizzi di quella
stessa porzione di memoria.
Ciao,
Nicola