View Full Version : [C] Problema puntatori
D4rkAng3l
28-04-2005, 17:46
Ciao, ho fatto un semplice programma che alloca dinamicamente un array di 100 interi, poi vorrei riempire questo array con un ciclo for ma qualcosa non funziona bene ed è come se mi inizializzasse a 0 solo il rpimo elemento (e quindi tutto l'array risulta essere inizializzato a 0)...mi sà che c'è qualcosa che non và nell'aritmetica dei puntatori ma non capisco cosa...
#include <stdlib.h>
#include <stdio.h>
/* Non riceve alcun parametro ed emette un puntatore a float */
int * get_mem(void);
int main(void){
int i;
int *puntatore; // Puntatore al primo valore float dell'array allocato
/* Alloca la memoria dinamicamente e metti il valore del puntatore uscente
dalla funzione get_mem nellaa variabile puntatore */
puntatore = get_mem();
printf("%p\n", puntatore);
for(i=0; i<=100; i++){
*(puntatore + i) = i; // Inizializza l'array con il valore di i
}
printf("\n%d\n", puntatore[0]);
printf("\n%d\n", puntatore[1]);
printf("\n%d\n", puntatore[2]);
system("PAUSE");
return 0;
}
/* La funzione get_mem non riceve alcun parametro in ingresso e restituisce un
puntatore al primo valore di tipo float dell'array di 100 elementi allocato
dinamicamente */
int *get_mem(void){
int *p; // Puntatore al primo elemento di tipo float dell'array
/* Alloca memoria per un array di 100 elementi di tipo float */
p = calloc(100, sizeof(int));
if(!p){ // Se calloc restituisce un puntatore NULL
printf("Errore di allocazione della memoria\n");
exit(1);
}
return p;
}
DanieleC88
28-04-2005, 18:14
for(i=0; i<=100; i++){
*(puntatore + i) = i; // Inizializza l'array con il valore di i
}
Quella la puoi sostituire con:
for (i = 0; i < 100; i++)
{
puntatore[i] = i; // Inizializza l'array con il valore di i
}
E fai attenzione: tu hai scritto "<= 100", non "< 100", ma in quel modo provi ad inizializzare 101 elementi dell'array, non 100 (da e compreso lo zero, fino a 100 incluso).
D4rkAng3l
28-04-2005, 18:22
Quella la puoi sostituire con:
for (i = 0; i < 100; i++)
{
puntatore[i] = i; // Inizializza l'array con il valore di i
}
E fai attenzione: tu hai scritto "<= 100", non "< 100", ma in quel modo provi ad inizializzare 101 elementi dell'array, non 100 (da e compreso lo zero, fino a 100 incluso).
ah ok grazie, però volevo fare un po' di prove proprio sull'aritmetica dei puntatori...mi ricordo che al corso di asm dato un vettore lo incrementavamo a mano con i puntatori...come posso fare questa cosa in C?
per il <= mi impappino sempre perchè non mi ricordo mai se l'ho fatto partire da 0 o da 1 mentre scrivo :D
AnonimoVeneziano
28-04-2005, 18:33
Strano , dovrebbe funzionare ....(a me funziona)
Che sia un bug del compilatore?
Prova a dichiarare la variabile "i" come "volatile" e vedi che succede.
Ciao
D4rkAng3l
28-04-2005, 18:40
cioè a te funziona il mio codice?compilare me lo compila però mi inizializza tutto il vettore a 0....
che vuol dire dichiarala come volatile?
DanieleC88
28-04-2005, 18:41
Prova a dichiarare la variabile "i" come "volatile" e vedi che succede.
Sicuro che possa aiutare? :rolleyes:
@D4rkAng3l: non ho ben capito cosa mi hai chiesto.
AnonimoVeneziano
28-04-2005, 18:42
cioè a te funziona il mio codice?compilare me lo compila però mi inizializza tutto il vettore a 0....
che vuol dire dichiarala come volatile?
Si , il tuo codice a me funziona perfettamente (tralasciando il <= :p)
Che compilatore usi?
Dichiarare la variabile come "volatile" intendo che invece di dichiarare "i" come :
int i;
di dichararla come :
volatile int i;
Dovrebbe bypassare eventuali ottimizzazioni buggate eseguite dal tuo compilatore (se il problema è effettivamente il compilatore) .
Ciao
AnonimoVeneziano
28-04-2005, 18:44
Sicuro che possa aiutare? :rolleyes:
@D4rkAng3l: non ho ben capito cosa mi hai chiesto.
Beh, se è un bug riguardante l' ottimizzazione della lettura dalla memoria del compilatore potrebbe aiutare
Ciao
D4rkAng3l
28-04-2005, 18:45
il compilatore è il dev c++ sotto win...
D4rkAng3l
28-04-2005, 18:52
cazzarola dichiarandola volatile funziona !!! e provando col codice originale con un altro compilatore funziona...ma il dev c++ non dovrebbe essere uno dei migliori?
in che modo hai capito che era proprio la variabile i a dare problemi e a dover essere dichairata come volatile?
cmq grazie mille...che rosicata però...tempo sprecato per uno stupido compilatore
AnonimoVeneziano
28-04-2005, 19:39
Si , allora è proprio un bug del compilatore .
I compilatori tendono a ottimizzare l'accesso alla memoria evitando di leggere una variabile + volte dalla memoria se questa non è stata modificata . "volatile" impone al compilatore di generare codice che rilegga la variabile ogni volta dalla memoria evitando tali ottimizzazioni .
Se nel compilatore c'è un bug relativo a tali ottimizzazioni (e quindi il compilatore non si accorge che la variabile in questione verrà modificata alla fine di ogni ciclo FOR e che sarà perciò necessario rileggerla anzichè riutilizzare il valore salvato nei registri che nel tuo caso era "0") con "volatile" lo si può bypassare, comunque se la versione di Dev C++ che stai usando non è una versione beta o development ma quella considerata stabile io farei un bug report ai programmatori.
Ciao
D4rkAng3l
28-04-2005, 19:41
si infatti ci avevo pensato anche io di farglielo sapere, che figata il mio primo bug trovato :D
VegetaSSJ5
28-04-2005, 21:02
devc++ usa gcc come compilatore. chissà se questo presunto bug sia presente per le versioni su tutte le piattaforme. io ricordo di aver fatto degli esempi del genere con devc++ ma non mi sembra di aver incontrato degli errori.
cmq x darkangel:
come ha detto danielec88 nel ciclo for inizializza i=1 oppure fai il controllo i<100 e non i<=100 perchè la 101esima volta vai a scrivere su una zona di memoria non allocata. fai questa correzione e poi rimanda in esecuzione il programma e vedi cosa succede.
D4rkAng3l
28-04-2005, 21:38
devc++ usa gcc come compilatore. chissà se questo presunto bug sia presente per le versioni su tutte le piattaforme. io ricordo di aver fatto degli esempi del genere con devc++ ma non mi sembra di aver incontrato degli errori.
cmq x darkangel:
come ha detto danielec88 nel ciclo for inizializza i=1 oppure fai il controllo i<100 e non i<=100 perchè la 101esima volta vai a scrivere su una zona di memoria non allocata. fai questa correzione e poi rimanda in esecuzione il programma e vedi cosa succede.
mmm si proverò, però errore logico a parte (quello del <=) col djgcc funziona perfettamente e poi a rigor di logica lui dovrebbe cmq eseguire il ciclo e scrivere il valore corrente di i in ogni zona dell'array allocato dinamicamente e poi dovrebbe sbroccare dopo quando và a scrivere in una zona di memoria non allocata e invece il dev c++ se non imposto la variabile come volatile mette uno 0 in ogni locazione dell'array...poi cmq proverò, magari il compilatore è fatto in modo tale da impostare tutte le locazioni a 0 se c'è qualcosa che non và...anche se mi sembra strano, non ci capisco molto ma da quello che sò i compilatori dovrebbero soloe seguire controlli sintattici e non logici....
VegetaSSJ5
28-04-2005, 21:49
per fare un po' di debug prova a mettere la printf proprio nel ciclo for...
Quella la puoi sostituire con:
for (i = 0; i < 100; i++)
{
puntatore[i] = i; // Inizializza l'array con il valore di i
}
E fai attenzione: tu hai scritto "<= 100", non "< 100", ma in quel modo provi ad inizializzare 101 elementi dell'array, non 100 (da e compreso lo zero, fino a 100 incluso).
Io preferisco invece l'aumento del puntatore *(p + i) = i (a parte l'errore del <=). Mi ricordo che faccio cosi' da quando a proposito di cio' il mio professore di Informatica I disse che se sulle tastiere non ci fossero le parentesi quadre tutti scriverebbero codice migliore :)
AnonimoVeneziano
29-04-2005, 14:28
Comunque su WinXP ho provato a installare Dev-C++ ultima versione ( 4.9.9.2 ) e il problema non c'è.
Te quale usi?
Ciao
D4rkAng3l
29-04-2005, 14:30
dice solo Dev C++ 4
mi sà che non è aggiornatissima...ora scaricherò anche io l'ultima versione
AnonimoVeneziano
29-04-2005, 15:39
Si, è una versione vecchia, scarica l'ultima
Ciao
guardate che scaricando l'ultima versione non risolvete nulla: gli sviluppatori del dev-c++ si occupano solo dell'ide (che tra l'altro è una porcheria immonda), il problema (se davvero c'è) è del porting per windows del gcc!!!
ho letto il codice del programmetto e sono rimasto veramente di sasso: cioè, ma veramente il gcc non è in grado di compilare quella cosa??? be', che dire... adesso odio linux e corredo un pochino di più di prima... O_o
sono indotto a pensare che il compilatore faccia un'ottimizzazione usando un registro come contatore del for al posto della variabile (probabilmente ECX sulla IA-32), però quando poi deve assegnare il valore di i allo slot corrente dell'array, va a leggere la variabile i in memoria (che sta ancora a 0) anziché il contatore!!! (non ho parole... :doh: )
ma dico, siete proprio sicuri che il gcc non è in grado di generare correttamente quel programmetto? avete provato a compilare da linea di comando senza usare il dev-c++?
Io preferisco invece l'aumento del puntatore *(p + i) = i (a parte l'errore del <=). Mi ricordo che faccio cosi' da quando a proposito di cio' il mio professore di Informatica I disse che se sulle tastiere non ci fossero le parentesi quadre tutti scriverebbero codice migliore :)
perché al tuo prof di Informatica I non gli suggerisci di passare a quest'altra notazione?
*(int*)(((char*)p) + i * sizeof(int)) = i;
:)
personalmente però preferisco
p[i] = i;
:)
e penso che se sulle tastiere italiane ci fossero scritte le parentesi graffe tutti scriverebbero codice migliore :)
ho letto il codice del programmetto e sono rimasto veramente di sasso: cioè, ma veramente il gcc non è in grado di compilare quella cosa??? be', che dire... adesso odio linux e corredo un pochino di più di prima... O_o
Scusa ma che colpa hanno linux e compagnia bella se quelli di cygwin hanno cannato a fare il proting :confused:
ciao ;)
Scusa ma che colpa hanno linux e compagnia bella se quelli di cygwin hanno cannato a fare il proting :confused:
ciao ;)
ma l'errore c'è anche sul gcc di linux?
io penso di si: suppongo che l'errore stia nella parte portabile di codice, cioè quella che si può compilare anche senza #ifdef (il parsing e la generazione del codice insomma)
non mi va di fare la prova su linux :p
ma l'errore c'è anche sul gcc di linux?
io penso di si: suppongo che l'errore stia nella parte portabile di codice, cioè quella che si può compilare anche senza #ifdef (il parsing e la generazione del codice insomma)
non mi va di fare la prova su linux :p
Ho provato con gcc-2.95,3.3,3.4,4.0 e qui su linux funziona tutto perfettamente. Non ho provato gcc-3.0-3.2 ma dubito che il problema sia li.
ciao ;)
AnonimoVeneziano
30-04-2005, 14:38
ho letto il codice del programmetto e sono rimasto veramente di sasso: cioè, ma veramente il gcc non è in grado di compilare quella cosa??? be', che dire... adesso odio linux e corredo un pochino di più di prima... O_o
sono indotto a pensare che il compilatore faccia un'ottimizzazione usando un registro come contatore del for al posto della variabile (probabilmente ECX sulla IA-32), però quando poi deve assegnare il valore di i allo slot corrente dell'array, va a leggere la variabile i in memoria (che sta ancora a 0) anziché il contatore!!! (non ho parole... :doh: )
ma dico, siete proprio sicuri che il gcc non è in grado di generare correttamente quel programmetto? avete provato a compilare da linea di comando senza usare il dev-c++?
GCC compila questa cosa benissimo. Probabilmente nel porting hanno rotto qualcosa, oppure era stato un bug passeggero di una versione un po' sfortunata (non sappiamo ancora che versione di DEV C++ abbia usato D4rkAng3l per compilare il programma) .
In entrambi i casi non mi sembra niente di grave .
Comunque linux non c'entra niente e l'odio verso un sistema operativo in particolare è un qualcosa di inutile (che sia windows, linux o chicchessia)
Ciao
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.