PDA

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...

Ubi-Wan
28-04-2005, 22:28
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

71104
29-04-2005, 23:35
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!!!

71104
29-04-2005, 23:41
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++?

71104
29-04-2005, 23:48
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 :)

VICIUS
30-04-2005, 00:51
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 ;)

71104
30-04-2005, 09:58
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

VICIUS
30-04-2005, 10:47
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