View Full Version : [C] programma scambio contenuto variabili con puntatore dà segmentation fault
phantom85
11-06-2008, 14:38
Ciao a tutti,
ho scritto un breve programma in C in cui c'è una funzione che passati due interi, scambia il contenuto delle due variabili e restituisce il puntatore al valore più grande.
Ho anche scritto un main per testarlo inizializzando le variabili.
Il problema è che nell'esecuzione da shell mi dà segmentation fault, mentre sul pc di un mio amico lo stesso programma funziona.
Come mai???
ecco il codice in allegato... HELP :confused:
Ciao a tutti,
ho scritto un breve programma in C in cui c'è una funzione che passati due interi, scambia il contenuto delle due variabili e restituisce il puntatore al valore più grande.
Ho anche scritto un main per testarlo inizializzando le variabili.
Il problema è che nell'esecuzione da shell mi dà segmentation fault, mentre sul pc di un mio amico lo stesso programma funziona.
Come mai???
ecco il codice in allegato... HELP :confused:
se vuoi una funzione che scambi semplicemente due numeri puoi usare una proprieta molto carina dello XOR che è questa:
a^=b;
b^=a;
a^=b;
che vuol dire
a=a^b;
b=b^a;
a=a^b;
esempio pratico
a=5 b=2
1° step a=a^b;----> a=5^2=7 stato: a=7 b=2
2° step b=b^a;----> b=2^7=5 stato: a=7 b=5
3° step a=a^b;----> a=7^5=2 stato: a=2 b=5
CVD :P
un'implementazione della funzioncina potrebbe essere:
void scambi(int *a, int *b)
{
(*a)^=(*b);
(*b)^=(*a);
(*a)^=(*b);
}
non restituisce nulla ma se tu passi i due numeri alla fine ti ritroverai i due numeri scambiati se vuoi che ti restituisca qualcosa metti un if e ti fai ritornare il puntatore alla variabile piu grande :P
Energy++
11-06-2008, 18:27
se vuoi una funzione che scambi semplicemente due numeri puoi usare una proprieta molto carina dello XOR che è questa:
a^=b;
b^=a;
a^=b;
che vuol dire
a=a^b;
b=b^a;
a=a^b;
esempio pratico
a=5 b=2
1° step a=a^b;----> a=5^2=7 stato: a=7 b=2
2° step b=b^a;----> b=2^7=5 stato: a=7 b=5
3° step a=a^b;----> a=7^5=2 stato: a=2 b=5
CVD :P
un'implementazione della funzioncina potrebbe essere:
void scambi(int *a, int *b)
{
(*a)^=(*b);
(*b)^=(*a);
(*a)^=(*b);
}
non restituisce nulla ma se tu passi i due numeri alla fine ti ritroverai i due numeri scambiati se vuoi che ti restituisca qualcosa metti un if e ti fai ritornare il puntatore alla variabile piu grande :P
mi piace troppo questa implementazione complimenti :)
mi piace troppo questa implementazione complimenti :)
thx all'uni con il mio prof in ste cose ci ha fatto na testa enorme :) ..cmq è buona perche è semplice, elegante ed ottimizzata perche gli operatori bitwise vengono processati molto piu velocemente rispetto alle operazioni di scambio e/o operazioni...che poi cmq con sti operatori bitwise spesso operazioni lunghissime si fanno in un paio di istruzioni del tipo invertire i numeri di una cifra il mio prof lo faceva con un'unica istruzioni usando gli operatori binari lol
phantom85
12-06-2008, 09:28
#include <stdio.h>
int *scambia (int a, int b) {
int swap, *max;
swap=a;
a=b;
b=swap;
if (a>b)
*max=a;
else
*max=b;
return max;
}
int main() {
int a=7, b=5;
printf ("Il più grande è: %d\n",scambia(a,b));
return 0;
}
per comodità te l'ho riscritto nei tag quote...
perchè scambi le variabili all'interno della funzione? quelle sono copie locali...
il puntatore max non è inizializzato... un puntatore si inizializza con un indirizzo di memoria, non con un valore...
la funzione torna un int *, quindi per accedere al valore effettivo devi fare una derefernziazione, cioè *(scambia(a,b))...
cmq la tua funzione non scambia nulla, o meglio, scambia solo i valori delle copie locali e "restituisce" (o almeno, ci prova) un puntatore ad una variabile che però verrà distrutta, in quanto è allocata sullo stack e alla chiusura della funzione quell'indirizzo che vorresti assegnarli non puoi sapere a cosa punterà...
Ringrazio tutti per l'aiuto!
Comunque il testo dell'esercizio è questo:
"Scrivete una funzione che scambi il valore di due variabili intere e restituisca un puntatore al valore massimo.
Testate la funzione richiamandola dal main del programma (non è necessario prevedere l’inserimento di input, inizaliz-
zate opportunamente le variabili per fare i test necessari)."
A questo punto cosa dovrei scrivere? L'implementazione con lo XOR è carina, ma non ce l'hanno mai spiegata, quindi non credo di poterla usare!!
Ti sconsiglio la soluzione degli XOR, per vari motivi.
E' peggiore sia come performance che come leggibilita' rispetto alla soluzione classica, che penso sia quella che il tuo professore vorrebbe.
Inoltre non permette di far capire se hai capito cosa vuol dire scambiare il valore di due variabili.
L'unico vantaggio della soluzione XOR e' che non fa uso di variabili d'appoggio, e sarebbe da usarsi in carenza di risorse/registri.
Cosa che oggi non capita spesso, soprattutto in un ambiente compilato dove non si ha il controllo sui registri.
phantom85
12-06-2008, 10:20
Ti sconsiglio la soluzione degli XOR, per vari motivi.
E' peggiore sia come performance che come leggibilita' rispetto alla soluzione classica, che penso sia quella che il tuo professore vorrebbe.
Inoltre non permette di far capire se hai capito cosa vuol dire scambiare il valore di due variabili.
L'unico vantaggio della soluzione XOR e' che non fa uso di variabili d'appoggio, e sarebbe da usarsi in carenza di risorse/registri.
Cosa che oggi non capita spesso, soprattutto in un ambiente compilato dove non si ha il controllo sui registri.
Grazie per il consiglio...sapresti correggere il mio codice in modo che tutto funzioni?
Grazie per il consiglio...sapresti correggere il mio codice in modo che tutto funzioni?
Non si possono scrivere soluzioni.
Ma pensaci bene.
Hai una bottiglia piena di vino e una piena di birra.
Devi scambiare il contenuto delle 2 bottiglie.
Hai a disposizione tante bottigile vuote quante ne vuoi.
Come fai?
Ti sconsiglio la soluzione degli XOR, per vari motivi.
E' peggiore sia come performance che come leggibilita' rispetto alla soluzione classica, che penso sia quella che il tuo professore vorrebbe.
Inoltre non permette di far capire se hai capito cosa vuol dire scambiare il valore di due variabili.
L'unico vantaggio della soluzione XOR e' che non fa uso di variabili d'appoggio, e sarebbe da usarsi in carenza di risorse/registri.
Cosa che oggi non capita spesso, soprattutto in un ambiente compilato dove non si ha il controllo sui registri.
non capisco perche sono peggiori a livello di performance :mbe: posso capire per la leggibilità ma le prestazioni :mbe:
non capisco perche sono peggiori a livello di performance :mbe: posso capire per la leggibilità ma le prestazioni :mbe:
Ecco qui
soluzione a XOR
3 letture da memoria
3 scritture su memoria
Nessuna possibilita' di accoppiamento istruzioni.
6 step sequenziali, che se va bene sono da 1 ciclo di clock l'uno
ma penso che lo XOR su memoria sia piu' pesante.
a ^= b;
00000026 mov eax,dword ptr [esi]
00000028 xor dword ptr [edi],eax
b ^= a;
0000002a mov eax,dword ptr [edi]
0000002c xor dword ptr [esi],eax
a ^= b;
0000002e mov eax,dword ptr [esi]
00000030 xor dword ptr [edi],eax
Soluzione classica
2 letture da memoria
2 scritture su memoria
1 copia di registro
Possibilita' di accoppiamento alta
Tutte le istruzioni sono sicuramente da 1 ciclo di clock
int c = a;
00000028 mov eax,dword ptr [esi]
0000002a mov ebx,eax
a = b;
0000002c mov eax,dword ptr [edi]
0000002e mov dword ptr [esi],eax
b = c;
00000030 mov dword ptr [edi],ebx
Ecco qui
soluzione a XOR
3 letture da memoria
3 scritture su memoria
Nessuna possibilita' di accoppiamento istruzioni.
6 step sequenziali, che se va bene sono da 1 ciclo di clock l'uno
ma penso che lo XOR su memoria sia piu' pesante.
a ^= b;
00000026 mov eax,dword ptr [esi]
00000028 xor dword ptr [edi],eax
b ^= a;
0000002a mov eax,dword ptr [edi]
0000002c xor dword ptr [esi],eax
a ^= b;
0000002e mov eax,dword ptr [esi]
00000030 xor dword ptr [edi],eax
Soluzione classica
2 letture da memoria
2 scritture su memoria
1 copia di registro
Possibilita' di accoppiamento alta
Tutte le istruzioni sono sicuramente da 1 ciclo di clock
int c = a;
00000028 mov eax,dword ptr [esi]
0000002a mov ebx,eax
a = b;
0000002c mov eax,dword ptr [edi]
0000002e mov dword ptr [esi],eax
b = c;
00000030 mov dword ptr [edi],ebx
azz grande....non ci avevo mai pensato....queste cose le hai fatte con un semplice debugger no?
thx all'uni con il mio prof in ste cose ci ha fatto na testa enorme :) ..cmq è buona perche è semplice, elegante ed ottimizzata perche gli operatori bitwise vengono processati molto piu velocemente rispetto alle operazioni di scambio e/o operazioni...che poi cmq con sti operatori bitwise spesso operazioni lunghissime si fanno in un paio di istruzioni del tipo invertire i numeri di una cifra il mio prof lo faceva con un'unica istruzioni usando gli operatori binari lol
Wow! Spero di non doverci mai lavorare con uno cosi!
Edit: ecco, dopo aver visto la risposta di gugo aggiungerei:"Visto a voler fare il figo, professore universitario?"
azz grande....non ci avevo mai pensato....queste cose le hai fatte con un semplice debugger no?
Il disassembler di visual studio.
Premature optimization is the root of all evil
http://en.wikipedia.org/wiki/Unix_philosophy
phantom85
12-06-2008, 11:30
Non si possono scrivere soluzioni.
Ma pensaci bene.
Hai una bottiglia piena di vino e una piena di birra.
Devi scambiare il contenuto delle 2 bottiglie.
Hai a disposizione tante bottigile vuote quante ne vuoi.
Come fai?
Non è lo stesso principio secondo cui ho utilizzato la variabile swap?
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.