Newsgroup: it.comp.lang.c
Titolo: Indici negativi in array ?

Il seguente codice e' stato postato come esempio per un bug di sendmail
sotto Unix. Quello che non capiso e' come mai la scrittura in un array
dando indice negativo non dia errori in esecuzione tipo segmentation
fault o access violation.
Non riesco neanche a capire come la scrittura su test[] possa andare a
sovrascrivere text[] che e' dichiarata dopo e non prima.
Qualcuno sa spiegarlo?
-- demo.c --
main()
{
        int test[10];
        char text[5]="test";
 
        test[-2]=0x6b636168;
        puts(text);
	}
Ciao a tutti
Paolo
-- 
azriel (at) 
freemail.it

Qualcuno sa spiegarlo?
Non c'è nessuna regola che indichi come devono essere allocate in memoria le
stringhe :-)
Ciao
Domenico Barra

 Qualcuno sa spiegarlo?
Un codice dal comportamento indefinito è libero di fare qualunque cosa.
EMG

 lecita in C.
Non mi pare che sia lecito accedere in questo modo a locazioni non
appartenente all'array.
EMG

appartenente all'array.
Infatti non lo è, nel caso tenti di accedere ad un valore non appartenente
all'array. Ma se dichiari un puntatore ad un elemento del tipo dell'array e
lo fai puntare ad array[2], dando 'ptr[-2]' ottieni proprio array[0]. Era
questo ciò che intendevo...
Ciao
Domenico Barra

questo ciň che intendevo...
Per cui, la frase :
"scrivere '*(str-2)', operazione questa totalmente lecita in C."
Andrebbe riscritta sottolineando il fatto che l'operazione e' lecita
finche' si accede ad elementi dell'array.
L'aritmetica dei puntatori e' definita solo nello spazio di
indirizzamento riservato all'array.
Stiamo attenti nel dare queste indicazioni.
--
Andrea Laforgia (ICQ 87230455)
------------------------------ 
#exclude <windows.h>

Un codice dal comportamento indefinito è libero di fare qualunque cosa.
Una spiegazione forse sono anche riuscito a darmela e se e' cosi'
dipende molto dalla piattaforma e dal compilatore.
Supponiamo di avere a disposizione uno stack di 100 byte, quindi il
registro Base Pointer indica 100 e all'inizio del programma per
semplicita' coincide con lo Stack Pointer.
BP=100
SP=100
Dopo aver dichiarato l'array di interi lo stack pointer segnera' 80 dato
che verranno allocati 2 byte per intero, quindi &test[0]=80,
&test[1]=82 ecc...
Se ora alloco la stringa in memoria questa sara' scritta da 79 a 75.
BP=100
SP=74
Se cerco di scrivere in test[-2] quello che faro' e' in effetti scrivere
in memoria a partire da 80-4=76 che e' proprio lo spazio di memoria
della stringa.
Questa e' l'unica spiegazione che mi sono riuscito a dare.
Ciao Paolo
-- 
azriel (at) 
freemail.it

 questo ciò che intendevo...
Ok.
EMG

Stiamo attenti nel dare queste indicazioni.
Già, mi era sfuggito, scusa :-/
Domenico Barra


 ha scritto:

No, sia
char	str[]="bravo";
sia bravo la stringa contenuta da 79 a 75 ( vabbe' 74 ... ). la 'b' sta in
74, r in 75 ... la 'o' in 78, lo 0 ( zero ) in 79. str contiene 74...
str[-2] e' quindi uguale a 74-2=72 ... che dovrebbe essere un indirizzo di
una variabile dichiarata successiva ( o precedente a seconda del compilatore
... ). D'altronde str[2]=='a' DEVE puntare a 74+2==76 ....
Non so se questo comportamento e' standard, ma a meno di sconvolgere le
interpretazioni di cose come str++ o str-- ( valide se str e' considerato un
puntatore a char * ) non vedo alternative

 Questa e' l'unica spiegazione che mi sono riuscito a dare.
Premesso che, come ti hanno già scritto, 'test[-2]' _non_ è un esempio 
di codice C da seguire, mi pare che tu abbia indovinato ( dettagli: su 
x86 di solito un int occupa 4 byte e nell'allocazione della spazio per 
la stringa entra in gioco l'allineamento ).
Esemplificando (sotto Linux):
[root@fokhouse /tmp]# gdb demo.g -q
(gdb) b 7
Breakpoint 1 at 0x80483e6: file demo.c, line 7.
(gdb) r
Starting program: /tmp/demo.g
Breakpoint 1, main () at demo.c:7
7               test[-2]=0x6b636168;
(gdb) i locals
test = {-1073742952, 1073785200, 1074771291, 134517896, 1073786464,
  -1073742876, -1073742952, 134513595, 134517876, 134517896}
text = "test"
(gdb) p &text
$1 = (char (*)[5]) 0xbffffb68
(gdb) p &test[-2]
$2 = (int *) 0xbffffb68
(gdb) q
The program is running.  Exit anyway? (y or n) y
[root@fokhouse /tmp]#
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)