Repository 32bit  Forum
Repository 64bit  Wiki

Puntatori e vettori.

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

Puntatori e vettori.

Messaggioda Mercyful » dom lug 12, 2009 19:56

Salve a tutti,
devo risolvere questo problema su un piccolo codice di un'esercizio che stavo facendo, ma non riesco a
capire perchè funziona solamente in certi casi. Vi sarei grato se mi dareste una mano a trovare l'errore!
Il codice è tutto quà:
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>

int plus(int, int);
int minus(int, int);
int (*choice(char))(int, int);
int execute_operation(int, int, int(*op)(int, int));

int main(int argc, char *argv[]) {

   int result = 0;
   int i = 0;
   int vect[2] = {3, 2};
   
   printf("The result is: %d\n", vect[(result = execute_operation(5, 2, choice('-')))]);
   printf("The result is: %d\n", vect[(result = execute_operation(4, 2, choice('-')))]);
   
   return EXIT_SUCCESS;
}

int plus(int a, int b) {
   return (a + b);
}

int minus(int a, int b) {
   return (a - b);
}

int (*choice(char c))(int, int) {
   switch (c) {
      case '+':
         return &plus;
      case '-':
         return &minus;
      default:
         return NULL;
   }
}

int execute_operation(int a, int b, int(*op)(int x, int y)) {
   return op((int)&a,(int)&b);
}


Non ci sono errori di compilazione, penso che sia colpa del pc a 64 bit anche se non ho l'OS a 64
Grazie in anticipo!!
Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6

Re: Puntatori e vettori.

Messaggioda robbybby » dom lug 12, 2009 20:15

Dacci qualche dettaglio in piu':
in quali casi funziona?
in quali casi non funziona?
cosa fa quando non funziona?

Poi ti converrebbe testare il valore ritornato da choice(), prima di dereferenziarlo. Se ritorna NULL, come minimo il tuo programmino va in crash.
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1174
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: Puntatori e vettori.

Messaggioda Mercyful » dom lug 12, 2009 20:26

l'output è sempre 2 , il risultato di choice è giusto in quanto mi da l'indirizzo di minus (anche se non è semplice da testare).
Bhe funziona nel senso che dovrebbe dare 3 e 2 ma da sempre 2.
Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6

Re: Puntatori e vettori.

Messaggioda Luke88 » dom lug 12, 2009 20:30

non ho mai giocato con i puntatori a funzione, comunque....

vect[] ha 2 elementi....
vect[0] = 3, vect[1] = 2, ma vect[2] o vect[3] non ci sono, quindi quando tu fai:
Codice: Seleziona tutto
printf("The result is: %d\n", vect[(result = execute_operation(5, 2, choice('-')))]);

gli dici di cercare il 4° elemento (vect[3]), e lui ovviamente non lo trova.
a parte che "result" non è necessario, potresti benissimo fare
Codice: Seleziona tutto
printf("The result is: %d\n", vect[execute_operation(5, 2, choice('-'))]);


ma poi:
Codice: Seleziona tutto
int execute_operation(int a, int b, int(*op)(int x, int y)) {
   return op((int)&a,(int)&b);
}

...uh?
perchè gli passi il cast a int dell indirizzo della variabile??
dovrebbe bastare
return op(a, b);

P.S.:
se usi la shell per compilare spesso sono utili anche i "warning", non solo gli errori di compilazione...
usa "gcc -Wall sorgente.c"
Ultima modifica di Luke88 il dom lug 12, 2009 20:39, modificato 1 volta in totale.
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )
Avatar utente
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: Puntatori e vettori.

Messaggioda m0rdr3d » dom lug 12, 2009 20:39

Luke88 ha scritto:...uh?
perchè gli passi il cast a int dell indirizzo della variabile??
dovrebbe bastare
return op(a, b);


Il problema è proprio quello, tu le operazioni le esegui sugli indirizzi delle variabili, per cui ti vengono ritornati valori a caso (nel mio caso -4).
Rimuovi gli operatori & e il cast ad int e tutto funzionerà.

P.S.: ovviamente il processore non può influire in questo caso, è il sistema operativo che alloca la memoria, indipendentemente dal processore sottostante.

P.S.: può un po' chiarirti le idee (o forse confondertele) provare a eseguire in execute_operation la seguente riga:
Codice: Seleziona tutto
printf( "a= %i, b= %i, &a= %i, &b= %i\n", a, b, &a, &b );

che ti stampa i valori di a, di b e di &a e &b
Avatar utente
m0rdr3d
Linux 2.4
Linux 2.4
 
Messaggi: 404
Iscritto il: dom dic 24, 2006 13:40
Slackware: Slackware64-current
Kernel: 3.4.*
Desktop: KDE 4.8.2

Re: Puntatori e vettori.

Messaggioda Mercyful » dom lug 12, 2009 21:02

@Luke88 si sembra ora con a e b funzioni, ma non è l'unico forse..., visto che funziona solo il primo.
il compilatore da shell lo uso sempre cosi... non mi da ne warning ne errori.

ora il risultato è 3 0 0 con questo codice:
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>

int plus(int, int);
int minus(int, int);
int (*choice(char))(int, int);
int execute_operation(int, int, int(*op)(int, int));

int main(int argc, char *argv[]) {

   int i = 0;
   int result = 0;
   int vect[2] = {3 , 2};
   
   
   printf("The result is: %d\n", vect[(result = execute_operation(5, 2, choice('-')))]);
   printf("The result is: %d\n", vect[(result = execute_operation(4, 2, choice('-')))]);
   printf("The result is: %d\n", i);
   
   return EXIT_SUCCESS;
}

int plus(int a, int b) {
   return (a + b);
}

int minus(int a, int b) {
   return (a - b);
}

int (*choice(char c))(int, int) {
   switch (c) {
      case '+':
         return &plus;
      case '-':
         return &minus;
      default:
         return NULL;
   }
}

int execute_operation(int a, int b, int(*op)(int x, int y)) {
   return op( a , b );
}

Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6

Re: Puntatori e vettori.

Messaggioda Luke88 » lun lug 13, 2009 9:00

Luke88 ha scritto:vect[] ha 2 elementi....
vect[0] = 3, vect[1] = 2, ma vect[2] o vect[3] non ci sono, quindi quando tu fai:
Codice: Seleziona tutto
printf("The result is: %d\n", vect[(result = execute_operation(5, 2, choice('-')))]);

gli dici di cercare il 4° elemento (vect[3]), e lui ovviamente non lo trova.
a parte che "result" non è necessario, potresti benissimo fare
Codice: Seleziona tutto
printf("The result is: %d\n", vect[execute_operation(5, 2, choice('-'))]);

:p
execute_operation(5, 2, choice('-')) ritorna l'intero 3, per cui tu vai a cercare vect[3].
hai dichiarato vect come vect[2]. ergo ci sono solo gli elementi vect[0] e vect[1].
devi dichiarare almeno vect[4] (e inserire gli elementi) se vuoi usare quell'array... oppure fai altre operazioni con execute_operation... a te la scelta...

anche se vai oltre la dimensione dell'array il compilatore non ti da errori perchè effettivamente non viene controllata la dimensione di vect[].
in pratica tu stai accedendo a memoria che potrebbe contenere un qualsiasi altro dato del programma stesso... se accedi troppo in la vai anche in segmentation fault, ovvero accedi a memoria a cui non potresti accedere, il sistema operativo se ne accorge e ti termina il programma... chiaro?

P.S.: consiglio il Kerninghan come buona lettura di programmazione C :p
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )
Avatar utente
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: Puntatori e vettori.

Messaggioda Mercyful » lun lug 13, 2009 9:37

Ciao,
si Luke hai ragione, però quello che sto facendo è quello che voglio fare, mancava giusto un'altra correzione,
in effetti non ho detto come doveva comportarsi il programma, in pratica deve accedere a quelle locazioni di memoria, e il risultato deve essere giusto.
Ecco, così dovrebbe essere giusto.
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>

int plus(int, int);
int minus(int, int);
int (*choice(char))(int, int);
int execute_operation(int, int, int(*op)(int, int));

int main(int argc, char *argv[]) {

   int result = 0;
   int result1 = 0;
   int vect[2] = {3 , 2};
   
   
   printf("The result is: %d\n", vect[(result1 = execute_operation(5, 2, choice('-')))]);
   printf("The result is: %d\n", vect[(result = execute_operation(4, 2, choice('-')))]);
   
   return EXIT_SUCCESS;
}

int plus(int a, int b) {
   return (a + b);
}

int minus(int a, int b) {
   return (a - b);
}

int (*choice(char c))(int, int) {
   switch (c) {
      case '+':
         return &plus;
      case '-':
         return &minus;
      default:
         return NULL;
   }
}

int execute_operation(int a, int b, int(*op)(int x, int y)) {
   return op( a , b );
}


Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6

Re: Puntatori e vettori.

Messaggioda Luke88 » lun lug 13, 2009 15:55

Mercyful ha scritto:si Luke hai ragione, però quello che sto facendo è quello che voglio fare,

vuoi accedere a memoria non allocata?
Mercyful ha scritto:mancava giusto un'altra correzione,
in effetti non ho detto come doveva comportarsi il programma, in pratica deve accedere a quelle locazioni di memoria, e il risultato deve essere giusto.
Ecco, così dovrebbe essere giusto.
Codice: Seleziona tutto
[...]
   printf("The result is: %d\n", vect[(result1 = execute_operation(5, 2, choice('-')))]);
   printf("The result is: %d\n", vect[(result = execute_operation(4, 2, choice('-')))]);


no, ti ho detto che è inutile mettere quel "result" o "result1".
fare:
printf("The result is: %d\n", vect[execute_operation(5, 2, choice('-'))]);
è uguale.
a meno che tu poi non riusi in qualche modo result e result1, ma qui non li riusi.

ragioniamo. calcoli execute_operation(5, 2, choice('-')). Questa funzione restituisce 5-2 = 3.
vect ha 2 elementi.
vect[0] = 3
vect[1] = 2
basta.
quando tu cerchi di accedere a vect[3] non accedi a qualcosa di definito! può essere qualsiasi cosa...
se vuoi che il primo printf restituisca "The result is: 3", o cambi quell'execute in:
execute_operation(2, 2, choice('-'))
oppure cambi vect in vect[4] = {0, 1, 2, 3 };
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )
Avatar utente
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: Puntatori e vettori.

Messaggioda Mercyful » lun lug 13, 2009 16:00

Bhe il risultato che ottengo non è un errore, è quello che voglio ottenere e sono i valori esatti delle sottrazioni (anche se solo di quelle due).
Hai provato a far girare il programma? Restituisce perfettamente i valori 3 e 2 e non per puro caso!
Hai capito il perchè?
Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6

Re: Puntatori e vettori.

Messaggioda 414N » lun lug 13, 2009 16:22

Io sinceramente non capisco a cosa serva vect...
Non ti interessa il risultato ritornato o dalla somma o dalla sottrazione? Che ragione c'è di usare il risultato come indice all'interno di un vettore di due elementi (tra l'altro senza bound checking)?
Avatar utente
414N
Iper Master
Iper Master
 
Messaggi: 2881
Iscritto il: mer feb 13, 2008 16:19
Località: Bulagna
Slackware: 14.0 (x64)
Kernel: 3.2.29
Desktop: LXDE

Re: Puntatori e vettori.

Messaggioda Luke88 » lun lug 13, 2009 16:26

Mercyful ha scritto:Bhe il risultato che ottengo non è un errore, è quello che voglio ottenere e sono i valori esatti delle sottrazioni (anche se solo di quelle due).
Hai provato a far girare il programma? Restituisce perfettamente i valori 3 e 2 e non per puro caso!
Hai capito il perchè?

si, l'ho capito il perchè. ma non ti sei accorto che quando accedi a vect[3] in realtà non stai accedendo al vettore ma aaccedi a result, e quando accedi a vect[2] in realtà non accedi al vettore ma accedi a result1.
sei andato in buffer overflow.
per puro c*lo result e result1 contengono i risultati rispettivamente di (4-2) e (5-2). e si trovano nella giusta posizione in memoria.
non stai usando vect. se non ci credi cambia vect in vect[2] = { 0, 0} e vedrai che "funzionerà" lo stesso.
se vuoi farlo smettere di funzionare, inserisci una qualsiasi variabile prima di vect[], ma dopo result e result1...
ad esempio:
Codice: Seleziona tutto
   int result = 0;
   int result1 = 0;
   int ciaociao[2] = {999, 1234};
   int vect[2] = {3 , 2};

e ora il primo risultato sarà 1234, e il secondo 999.
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )
Avatar utente
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: Puntatori e vettori.

Messaggioda Mercyful » lun lug 13, 2009 16:36

Si lo so, ma non è per c**o che mi esce il risultato, è perchè stavo cercando di capire come mette i risultati lo stack.
I valori successivi sono si i valori di result e result1 ma non per c**o.
I valori poi che stanno dentro il vettore non li uso, sono solo per un eventuale gioco che volevo fare con l'operatore modulo.
Infatti come ho detto prima funziona solamente con quelle due sottrazioni, se vai oltre con gli indici ottieni altri risultati.
Non mi hai detto se l'hai provato, dovrebbe dare lo stesso risultato anche a te per via dello stack.
Mi sbaglio?
Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6

Re: Puntatori e vettori.

Messaggioda Luke88 » lun lug 13, 2009 16:40

Mercyful ha scritto:Si lo so, ma non è per c**o che mi esce il risultato, è perchè stavo cercando di capire come mette i risultati lo stack.
I valori successivi sono si i valori di result e result1 ma non per c**o.

vabbè, ma allora dillo che l'overflow era pposta :lol:
credevo cercassi di riavere i valori di vect!
Mercyful ha scritto:I valori poi che stanno dentro il vettore non li uso, sono solo per un eventuale gioco che volevo fare con l'operatore modulo.
Infatti come ho detto prima funziona solamente con quelle due sottrazioni, se vai oltre con gli indici ottieni altri risultati.
Non mi hai detto se l'hai provato, dovrebbe dare lo stesso risultato anche a te per via dello stack.
Mi sbaglio?

l'ho provato, si...
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )
Avatar utente
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: Puntatori e vettori.

Messaggioda Mercyful » lun lug 13, 2009 16:51

Si era quello che volevo fare... non ho detto mai cosa volevo fare..
Se funziona da te è un bene funziona tutto correttamente..

grazie mille! !
Avatar utente
Mercyful
Linux 2.0
Linux 2.0
 
Messaggi: 196
Iscritto il: ven lug 25, 2008 17:20
Località: Torino
Nome Cognome: Ilario Pittau
Slackware: 13.0
Kernel: 2.6.29.6-generic
Desktop: xfce 4.6


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite