[C] Strutture e puntatori
Ciao ragazzi. Avrei bisogno del vostro aiuto.
Sto lavorando sulle strutture e sui puntatori all'interno di questo codice (vi riporto la parte in cui ho problemi):
Mi dà il seguente exc_bad_access(code=1, address=0xffffffff 5bdd89e0).
Non so se sia corretto procedere nel seguente modo. Considerate che sto familiarizzando soltanto da poco con le strutture e questo codice ne è, per l'appunto, la prova.
Inoltre volevo chiedervi se sia corretto allocare dinamicamente p all'interno della prima funzione (inizio) o se si debba fare nel main e/o nell'altra funzione (stampa).
Ciò che vorrei fare è tenere in memoria i valori e copiarli all'interno di un file di testo.
Spero possiate aiutarmi a capire dove sbaglio.
Vi ringrazio.
Alex
Sto lavorando sulle strutture e sui puntatori all'interno di questo codice (vi riporto la parte in cui ho problemi):
#include <stdio.h> #include <stdlib.h> struct prova { /*variables */ float *p; } pro; void inizio (struct prova); void stampa (struct prova); int main(){ inizio(pro); stampa(pro); return 0; } void inizio (struct prova pro){ int t; pro.p=(float*)malloc(5 * sizeof(float)); t=0; pro.p[0]=2; } void stampa (struct prova pro){ int i,t; for(i=0; i<5; i++){ pro.p[t+1]=pro.p[t]; // Linea corrispondente all'errore. Prima di utilizzare le strutture, mi restituiva il valore 2. printf("Stampo: %d -> %f\n", i, pro.p[t+1]); } }
Mi dà il seguente exc_bad_access(code=1, address=0xffffffff 5bdd89e0).
Non so se sia corretto procedere nel seguente modo. Considerate che sto familiarizzando soltanto da poco con le strutture e questo codice ne è, per l'appunto, la prova.
Inoltre volevo chiedervi se sia corretto allocare dinamicamente p all'interno della prima funzione (inizio) o se si debba fare nel main e/o nell'altra funzione (stampa).
Ciò che vorrei fare è tenere in memoria i valori e copiarli all'interno di un file di testo.
Spero possiate aiutarmi a capire dove sbaglio.
Vi ringrazio.
Alex
Risposte
Perché in [inline]inizio[/inline] allochi 5 interi per un puntatore a [inline]float[/inline]?
Grazie per aver risposto, Raptorista. Hai ragione!
Non ho tenuto conto che per allocare la memoria in quel caso al posto di int dovevo sostituire float
EDIT: sostituendo
mi compare comunque lo stesso errore...
Non ho tenuto conto che per allocare la memoria in quel caso al posto di int dovevo sostituire float

EDIT: sostituendo
pro.p=(float*)malloc(5 * sizeof(float));
mi compare comunque lo stesso errore...
Nel ciclo stai usando la variabile [inline]t[/inline] come indice in [inline]pro.p[t+1]=pro.p[t][/inline] anziché [inline]i[/inline].
Hai perfettamente ragione. Ad ogni modo, in quel modo doveva restituirmi in stampa i valori da 1 a 5 con p[t+1]=2, se non sbaglio.
Ho provato però ad eseguirlo senza ciclo for ma l'errore continua ad essere presente. E' possibile che stia sbagliando qualcosa nell'allocazione dinamica o nell'utilizzo delle variabili puntatore all'interno delle due funzioni?
In teoria, ciò che dovrebbe restituirmi dovrebbe essere il valore 2, come fissato nella funzione inizio... Non riesco proprio a capire come mai non riesca a visualizzare in stampa questo valore
EDIT: Allocando dinamicamente la memoria per p all'interno della funzione stampa non compare più il problema, malgrado si perda l'informazione contenuta all'interno della funzione inizio. Infatti mi stampa il valore 0.
C'è un modo per allocare dinamicamente questo puntatore senza che venga persa l'informazione contenuta all'interno delle altre funzioni? Inizialmente p[5] era una variabile globale...
Potreste inoltre dirmi come rendere equivalenti i seguenti codici? Vi ringrazio sin da ora!
e
Ho provato però ad eseguirlo senza ciclo for ma l'errore continua ad essere presente. E' possibile che stia sbagliando qualcosa nell'allocazione dinamica o nell'utilizzo delle variabili puntatore all'interno delle due funzioni?
In teoria, ciò che dovrebbe restituirmi dovrebbe essere il valore 2, come fissato nella funzione inizio... Non riesco proprio a capire come mai non riesca a visualizzare in stampa questo valore

EDIT: Allocando dinamicamente la memoria per p all'interno della funzione stampa non compare più il problema, malgrado si perda l'informazione contenuta all'interno della funzione inizio. Infatti mi stampa il valore 0.
C'è un modo per allocare dinamicamente questo puntatore senza che venga persa l'informazione contenuta all'interno delle altre funzioni? Inizialmente p[5] era una variabile globale...
Potreste inoltre dirmi come rendere equivalenti i seguenti codici? Vi ringrazio sin da ora!
#include <stdio.h> #include <stdlib.h> struct prova { /*variables */ float *p; } pro; void inizio (struct prova); void stampa (struct prova); int main(){ inizio(pro); stampa(pro); return 0; } void inizio (struct prova pro){ int t; pro.p=(float*)malloc(5 * sizeof(float)); t=0; pro.p[0]=2; } void stampa (struct prova pro){ int t; pro.p[t+1]=pro.p[t]; // Cosa restituisce? printf("Stampo: %f\n", pro.p[t+1]); }
e
#include <stdio.h> #include <stdlib.h> float p[5]; void inizio (); void stampa (); int main(){ inizio(); stampa(); return 0; } void inizio (void){ int t; t=0; p[0]=2; } void stampa (void){ int t; p[t+1]=p[t]; // Cosa dovrebbe restituire? printf("Stampo: %f\n", p[t+1]); }
Non mi stai seguendo! È sbagliato quando fai
perché [inline]t[/inline] non è stato inizializzato. Non ha un valore, quindi non puoi accedere all'elemento t-esimo. Quello che succede nella pratica è che [inline]t[/inline] contiene un valore casuale, e quando il programma va a leggere in quella posizione legge spazzatura. Se assegnassi [inline]t=0[/inline] tra le due istruzioni, funzionerebbe.
int t; pro.p[t+1]=pro.p[t];
perché [inline]t[/inline] non è stato inizializzato. Non ha un valore, quindi non puoi accedere all'elemento t-esimo. Quello che succede nella pratica è che [inline]t[/inline] contiene un valore casuale, e quando il programma va a leggere in quella posizione legge spazzatura. Se assegnassi [inline]t=0[/inline] tra le due istruzioni, funzionerebbe.
Grazie mille, Rapsodista. Io ho modificato (sperando di aver compreso quello che mi stai suggerendo, anche se capito in ritardo
nel seguente modo:
Però, anche in questo caso, mi dà errore alla linea pro.p[t+1]=pro.p[t].
Se, invece delle strutture e dei puntatori, utilizzo variabili globali e array, l'errore scompare, sebbene mi stampi come valore 0 e non 2 come mi aspetterei.
E' anche vero, però, che ciò che vorrei provare a fare è: 1) scrivere una funzione che, all'interno di un ciclo for, inizializzi alcune variabili, tra cui p[t]; 2) svolgere delle operazioni attraverso un'altra funzione, che in questo caso è la funzione stampa(), in cui utilizzo quelle variabili.
La mia perplessità è anche legata all'utilizzo della funzione malloc(): è corretto quello che sto al momento facendo? Basta allocare dinamicamente lo spazio in memoria all'interno della funzione inizio() anche se le variabili sono utilizzate nella funzione stampa(), entrambe poi richiamate nel main? Il codice iniziale era il secondo, quello con gli array statici, poi trasformati in puntatori per provare a comprendere meglio questi argomenti.
Ti ringrazio, ad ogni modo, per tutto il tempo e l'aiuto che mi stai fornendo e ti chiedo scusa se ogni tanto sono lento a comprendere e a seguire i consigli e i suggerimenti: ho tante domande e curiosità riguardo a questi argomenti e vorrei capirli completamente
Grazie ancora

#include <stdio.h> #include <stdlib.h> struct prova { /*variables */ float *p; } pro; void inizio (struct prova); void stampa (struct prova); int main(){ inizio(pro); stampa(pro); return 0; } void inizio (struct prova pro){ int t; pro.p=(float*)malloc(5 * sizeof(float)); t=0; pro.p[0]=2; } void stampa (struct prova pro){ int t; t=0; pro.p[t+1]=pro.p[t]; // Cosa restituisce? printf("Stampo: %f\n", pro.p[t+1]); }
Però, anche in questo caso, mi dà errore alla linea pro.p[t+1]=pro.p[t].
Se, invece delle strutture e dei puntatori, utilizzo variabili globali e array, l'errore scompare, sebbene mi stampi come valore 0 e non 2 come mi aspetterei.
E' anche vero, però, che ciò che vorrei provare a fare è: 1) scrivere una funzione che, all'interno di un ciclo for, inizializzi alcune variabili, tra cui p[t]; 2) svolgere delle operazioni attraverso un'altra funzione, che in questo caso è la funzione stampa(), in cui utilizzo quelle variabili.
La mia perplessità è anche legata all'utilizzo della funzione malloc(): è corretto quello che sto al momento facendo? Basta allocare dinamicamente lo spazio in memoria all'interno della funzione inizio() anche se le variabili sono utilizzate nella funzione stampa(), entrambe poi richiamate nel main? Il codice iniziale era il secondo, quello con gli array statici, poi trasformati in puntatori per provare a comprendere meglio questi argomenti.
Ti ringrazio, ad ogni modo, per tutto il tempo e l'aiuto che mi stai fornendo e ti chiedo scusa se ogni tanto sono lento a comprendere e a seguire i consigli e i suggerimenti: ho tante domande e curiosità riguardo a questi argomenti e vorrei capirli completamente

L'errore è nel fatto che passi la struttura per valore invece che per riferimento. Insomma pro viene "mascherata" dalle variabili locali pro e non viene modificata in nessun modo. Comunque tutto continua ad essere globale.
Ti ringrazio vic85.
Potresti spiegarmi meglio come posso risolvere questo problema?
E' quantomeno corretta la parte dell'allocazione?
Per quanto riguarda il valore: dovrei in questo riscrivere pro.p[0]=2.; nella funzione stampa o c'e' un modo per riprendere questo valore? Sono un neofita, perdonatemi le domande ripetute e probabilmente anche banali. Vi ringrazio
Potresti spiegarmi meglio come posso risolvere questo problema?
E' quantomeno corretta la parte dell'allocazione?
Per quanto riguarda il valore: dovrei in questo riscrivere pro.p[0]=2.; nella funzione stampa o c'e' un modo per riprendere questo valore? Sono un neofita, perdonatemi le domande ripetute e probabilmente anche banali. Vi ringrazio
Considerando che allochi una quantità fissa di elementi, puoi anche evitare di allocare memoria dinamicamente.
#include <stdio.h> #include <stdlib.h> struct prova { float p[5]; }; void inizio(struct prova * pr); void stampa(struct prova const * pr); int main() { struct prova pro; inizio(&pro); stampa(&pro); return 0; } void inizio(struct prova * pro) { if( pro ) { *pro = (struct prova){ { 2 } }; } } void stampa(struct prova const * pro) { for( int t = 0; t != 5; ++t ) { printf("prova[%d] = %g\n", t, pro->p[t]); } }
Ti ringrazio vic85!
Effettivamente allocare dinamicamente qualcosa che contiene un numero fissato di elementi non ha senso.
Posso chiederti in quali casi e' conveniente utilizzare l'allocazione dinamica?
Effettivamente allocare dinamicamente qualcosa che contiene un numero fissato di elementi non ha senso.
Posso chiederti in quali casi e' conveniente utilizzare l'allocazione dinamica?
È una domanda complessa. In generale ogni volta che non sai la dimensione in anticipo o che devi allocare molta memoria. Comunque avresti potuto anche allocare direttamente l'intera struttura.
Grazie mille, vict85! Proverò ad allocare l'intera struttura, giusto per capire come si fa
Grazie ancora per l'aiuto.
EDIT:
E' corretto procedere in questo modo?

Grazie ancora per l'aiuto.
EDIT:
E' corretto procedere in questo modo?
struct book { int b[100]; }*book1; void print(struct book *); int main(){ book1=(struct book *)malloc(sizeof(book1)); print(&book1); } void print(struct book *book1){ int i; srand(time(NULL)); for(i=0;i<100;i++){ book1->b[i]=rand()%10; printf("Libro b[%d] %d\n", i, book1->b[i]); } }