View Full Version : [C] Clion - Strano comportamento della console IDE
Come da titolo, sto usando CLion come IDE.
Non riesco a capire per quale ragione mi runna il programma a metà
In parole povere: devo stampare il contenuto di una matrice, a volte (raramente) lo stampa tutto, a volte si ferma prima della fine.
Con il terminale di ubuntu nessun problema: stampa tutta la matrice.
Probabilmente è una banalità, ma non riesco a capire dove mettere le mani.
Se avete qualche idea, tutto è ben accetto :D
se non posti nemmeno del codice di esempio da provare nessuno credo abbia la palla di vetro...
Il motivo per il quale non ho postato il codice è perchè su terminale ubuntu fila tutto liscio, quindi ho pensato si trattasse di qualche impostazione errata nell'IDE.
In ogni caso, allego la funzione che crea la matrice, e la funzione che la stampa
Posto** creaSala(){
Posto **v = calloc(numerofile,sizeof(Posto*));
assert(v!=NULL);
int fila ;
int posto;
Posto *seat;
for(fila=0;fila<numerofile;fila++){
*(v+fila)=calloc(postixfila,sizeof(Posto));
assert(*(v+fila)!= NULL);
for(posto=0;posto<postixfila;posto++){
seat = nuovoPosto(posto+1, fila+1);
v[fila][posto] = *seat;
}
}
return v;
}
void stampaSala(Posto **sala){
int fila;
int posto;
int numposto;
int numfila;
Posto *temp;
for(fila =0; fila<numerofile; fila++){
printf("--- Fila numero %d --- \n",numfila+1 );
for(posto=0;posto<postixfila;posto++){
temp = &sala[fila][posto];
numposto =getnumposto(temp);
numfila = getnumfila(temp);
printf("numero di fila: %d \n",numfila );
printf("numero di posto: %d \n",numposto );
if(temp->occupato==false){
printf("il posto è libero \n\n");
}
}
}
}
Considerate che è abbastanza abbozzato come codice
fa una cosa,
all'interno del main, metti un return 0; come ultima istruzione, poi fai girare il tuo programma nel terminale di ubuntu e scrivi "echo $?" dopo che il programma finisce. Controlla che il valore ritornato e' 0.
se non lo e', c'e' qualcosa che crasha da qualche parte. non vedo nessun motivo per cui il tuo IDE dovrebbe comportarsi diversamente se il programme e' scritto correttamente.
Il valore returnato è 0, quindi nessun problema.
Ho notato un'altra cosa: con lo stesso input il programma si "ferma" in diversi punti.
A volte scrive qualche riga, a volte quasi tutte, a volte tutto.
Potrebbe essere un problema di timeout ?
sottovento
10-05-2016, 07:37
cosa fa nuovoPosto()?
cosa fa nuovoPosto()?
È il costruttore della struct posto.
Gli argomenti indicano fila e numero del posto.
sottovento
10-05-2016, 09:30
È il costruttore della struct posto.
Gli argomenti indicano fila e numero del posto.
Ho capito; tuttavia rimane la curiosita' di vederla, e magari di vedere le parti che mancano, tanto per avere un quadro piu' completo. Non credo siano troppo lunghe, penso che si possano postare qui, giusto?
Quello che mi fa pensare e' l'uso della nuovoPosto();
seat = nuovoPosto(posto+1, fila+1);
L'hai implementata allocando memoria?
Ho capito; tuttavia rimane la curiosita' di vederla, e magari di vedere le parti che mancano, tanto per avere un quadro piu' completo. Non credo siano troppo lunghe, penso che si possano postare qui, giusto?
Quello che mi fa pensare e' l'uso della nuovoPosto();
seat = nuovoPosto(posto+1, fila+1);
L'hai implementata allocando memoria?
Nessun problema, ti allego Posto.c
#include <stdlib.h>
#include "Posto.h"
#include <stdbool.h>
Posto *nuovoPosto(int numposto, int numfila){
Posto *x = (Posto*)calloc(1,sizeof(Posto));
x->numfila = numfila;
x->numposto = numposto;
x->occupato = false;
}
void cancellaPosto(Posto *x){
free(x);
}
void prenotaposto(Posto *x){
x->occupato=true;
}
void cancellaprenotazione(Posto *x){
x->occupato=false;
}
int getnumposto(Posto *x){
return x->numposto;
}
int getnumfila(Posto *x){
return x->numfila;
}
void setnum(Posto *x,int num){
x->numposto=num;
}
void setfila(Posto *x,int fila){
x->numfila=fila;
}
questo invece è il "distruttore" della matrice
void distruggiSala(Posto **v,int n){
int i;
for(i=0;i<n;i++){
free(v[i]);}
free(v) ;
}
Il main per ora fa altro che inizializzare le variabili globali int postixfila e int numerofile e chiamare i tre metodi: manca ancora tutta la parte sulla programmazione di rete.
Credo comunque di aver dimenticato una free(seat), ma ti anticipo subito che il risultato non cambia
sottovento
10-05-2016, 10:29
Ok, grazie.
Una cosa che salta subito all'occhio e'
seat = nuovoPosto(posto+1, fila+1);
questa va ad allocare memoria per un nuovo posto ed inizializza il contenuto correttamente; poi vai a fare
v[fila][posto] = *seat;
cioe' assegni il contenuto dei campi al record allocato precedentemente.
Cosa succede a seat? Sembra proprio che venga perso, vale a dire stai perdendo memoria.
Non credo che questo sia il tuo problema, ma prima di tutto lo sistemerei, visto che il leakage e' in un ciclo e quindi vai a perdere piu' record.
Per quanto riguarda il problema della stampa parziale: hai provato a mettere una printf() ad ogni esecuzione del ciclo?
Ok, grazie.
Una cosa che salta subito all'occhio e'
seat = nuovoPosto(posto+1, fila+1);
questa va ad allocare memoria per un nuovo posto ed inizializza il contenuto correttamente; poi vai a fare
v[fila][posto] = *seat;
cioe' assegni il contenuto dei campi al record allocato precedentemente.
Cosa succede a seat? Sembra proprio che venga perso, vale a dire stai perdendo memoria.
Non credo che questo sia il tuo problema, ma prima di tutto lo sistemerei, visto che il leakage e' in un ciclo e quindi vai a perdere piu' record.
Per quanto riguarda il problema della stampa parziale: hai provato a mettere una printf() ad ogni esecuzione del ciclo?
Quindi la free(seat) va inserita nel ciclo, non fuori ?
In ogni caso ho provato a mettere una printf() ovunque, il processo semplicemente si interrompe all'improvviso, ogni volta in un punto diverso.
In ogni caso, grazie per il tuo aiuto !
sottovento
10-05-2016, 10:54
Quindi la free(seat) va inserita nel ciclo, non fuori ?
In ogni caso ho provato a mettere una printf() ovunque, il processo semplicemente si interrompe all'improvviso, ogni volta in un punto diverso.
In ogni caso, grazie per il tuo aiuto !
Ad essere sinceri non ho visto alcuna free(seat) nel codice che hai postato, quindi non so se e dove l'hai posizionata.
Hai creato una funzione cancellaPosto(), ti suggerisco di usarla.
Per quanto riguarda la nuovoPosto() non fai il controllo se la memoria e' effettivamente allocata. Dalle altre parti hai messo un'assert, ti suggerisco di fare altrettanto.
Tornando al problema principale (i.e. il processo si interrompe all'improvviso): purtroppo stiamo lavorando su pezzi di codice, quindi si possono fare solo delle ipotesi.
Quando un processo si interrompe all'improvviso, normalmente controllo che la memoria a cui ha fatto accesso sia valida (allocata, inizializzata, ...).
Purtroppo non lo si puo' fare, qui; lo puoi fare? Se ti serve un parere, puoi pubblicare il codice per intero.
Altra cosa: i cicli sono regolati dalle variabili numerofila e postixfila ed anche quelli compaiono nel codice all'improvviso. Occorrerebbe accertarsi che il loro valore sia corretto e non vengano sovrascritte inavvertitamente.
Inoltre, conoscendomi (e' un errore che faccio spesso) controllerei anche lo SCOPE di quelle variabili: magari hanno il valore corretto ma inavvertitamente potrei aver dichiarato una variabile locale con lo stesso nome, che quindi andrebbe a nascondere quella con il valore corretto. Sei in questo caso?
Quindi, visto che parlavamo di printf(), stamperei:
- le variabili numerofile e postixfila all'inizio dei cicli;
- le variabili di ciclo, le vorrei vedere incrementarsi;
- metterei una printf() di saluti alla fine del programma, per vedere se effettivamente arrivo fino li'.
Infine mi accerterei che non sia uno dei soliti problemi di certi IDE tipo: bufferizzazione dell'output, chiusura immediata della finestra al termine dell'esecuzione, ecc.
Ad essere sinceri non ho visto alcuna free(seat) nel codice che hai postato, quindi non so se e dove l'hai posizionata.
Hai creato una funzione cancellaPosto(), ti suggerisco di usarla.
Si hai ragione, ma ho scritto in un post precedente di averla dimenticata.
Non ero sicuro se metterla dentro o fuori dal ciclo.
Tornando al problema principale (i.e. il processo si interrompe all'improvviso): purtroppo stiamo lavorando su pezzi di codice, quindi si possono fare solo delle ipotesi.
Quando un processo si interrompe all'improvviso, normalmente controllo che la memoria a cui ha fatto accesso sia valida (allocata, inizializzata, ...).
Purtroppo non lo si puo' fare, qui; lo puoi fare? Se ti serve un parere, puoi pubblicare il codice per intero.
E' praticamente tutto il codice, il main è semplicemente
int main() {
printf("Inserire numero di file: ");
scanf("%d",&numerofile);
printf("Inserire posti per fila: ");
scanf("%d",&postixfila);
Sala = creaSala();
stampaSala(Sala);
distruggiSala(Sala,numerofile);
return 0;}
Ecco il link a tutto il programma (ovviamente escluso Posto.c)
http://paste.ofcode.org/pJjRr76KqbHXM4KeMV9Jaf
Posto.h
http://paste.ofcode.org/FUrpAijA6tLFa2RhnQe8r9
Altra cosa: i cicli sono regolati dalle variabili numerofila e postixfila ed anche quelli compaiono nel codice all'improvviso. Occorrerebbe accertarsi che il loro valore sia corretto e non vengano sovrascritte inavvertitamente.
Sono variabili globali, credo di averlo accennato qualche post dietro.
Inoltre, conoscendomi (e' un errore che faccio spesso) controllerei anche lo SCOPE di quelle variabili: magari hanno il valore corretto ma inavvertitamente potrei aver dichiarato una variabile locale con lo stesso nome, che quindi andrebbe a nascondere quella con il valore corretto. Sei in questo caso?
Quindi, visto che parlavamo di printf(), stamperei:
- le variabili numerofile e postixfila all'inizio dei cicli;
- le variabili di ciclo, le vorrei vedere incrementarsi;
- metterei una printf() di saluti alla fine del programma, per vedere se effettivamente arrivo fino li'.
Infine mi accerterei che non sia uno dei soliti problemi di certi IDE tipo: bufferizzazione dell'output, chiusura immediata della finestra al termine dell'esecuzione, ecc.
Ora provo tutto, grazie mille !
sottovento
10-05-2016, 11:27
Me n'e' scappata una importante. Perdona, la vecchiaia...
#include <stdlib.h>
#include "Posto.h"
#include <stdbool.h>
Posto *nuovoPosto(int numposto, int numfila){
Posto *x = (Posto*)calloc(1,sizeof(Posto));
x->numfila = numfila;
x->numposto = numposto;
x->occupato = false;
}
questa funzione non ritorna nulla. Questo potrebbe essere il tuo problema: quando sei fortunato, becchi un'area di memoria per seat che e' valida, scrivi e prosegui felicemente.
Altrimenti il programma puo' far di tutto, compreso terminare inaspettatamente.
Me n'e' scappata una importante. Perdona, la vecchiaia...
#include <stdlib.h>
#include "Posto.h"
#include <stdbool.h>
Posto *nuovoPosto(int numposto, int numfila){
Posto *x = (Posto*)calloc(1,sizeof(Posto));
x->numfila = numfila;
x->numposto = numposto;
x->occupato = false;
}
questa funzione non ritorna nulla. Questo potrebbe essere il tuo problema: quando sei fortunato, becchi un'area di memoria per seat che e' valida, scrivi e prosegui felicemente.
Altrimenti il programma puo' far di tutto, compreso terminare inaspettatamente.
Pardon, dimenticanza mia.
Ho inserito un "return x" ma niente, continua ad interrompersi.
Strano che il compilatore non mi abbia detto nulla.
Tu hai provato a farlo partire ?
Ecco cosa fa
http://abload.de/img/schermatadel2016-05-166jhu.jpg
sottovento
10-05-2016, 11:45
Pardon, dimenticanza mia.
Ho inserito un "return x" ma niente, continua ad interrompersi.
Strano che il compilatore non mi abbia detto nulla.
Tu hai provato a farlo partire ?
L'ho provato ora. Ho dovuto fare alcune modifiche minori per poterlo compilare.
Sembra funzionare.
Cmq resta la curiosita': hai aggiunto le printf()?
Soprattutto: immagino che il tuo ambiente ti dia a disposizione un debugger. Hai provato a farlo girare con il debugger? Cosa ti dice?
sottovento
10-05-2016, 11:51
Ops, ho visto l'immagine DOPO aver postato la mia risposta.
Come ti dicevo, ho provato a farlo girare e sembra funzionare, ma cosi' non e' nel tuo ambiente.
Nel mio test ho desunto l'implementazione di Posto.h dal resto del codice; potresti pubblicare invece la tua versione?
L'ho provato ora. Ho dovuto fare alcune modifiche minori per poterlo compilare.
Sembra funzionare.
Cmq resta la curiosita': hai aggiunto le printf()?
Soprattutto: immagino che il tuo ambiente ti dia a disposizione un debugger. Hai provato a farlo girare con il debugger? Cosa ti dice?
Si, ho messo le printf dove dicevi tu, e tutto fino all'interruzione funziona bene.
Il debugger me lo runna correttamente, ma non so come interpretare questo fatto :|
ecco Posto.h
http://paste.ofcode.org/FUrpAijA6tLFa2RhnQe8r9
sottovento
10-05-2016, 12:15
Davvero strano, anche perche' a me continua a funzionare.
C'e' un altro errore minore:
printf("--- Fila numero %d --- \n", numfila + 1);
numfila in quel momento non e' inizializzato, quindi questa istruzione non e' corretta, puoi sostituirla con
printf("--- Fila numero %d --- \n", fila + 1);
Tornando alle cose serie: sembra che ci sia bisogno di un esorcista.
Sarebbe opportuno provare ad escludere delle parti per vedere se almeno si arriva alla fine. Il programma pero' e' gia' piuttosto scarno, non so cosa si possa escludere.
Proverei escludendo l'inizializzazione (i.e. commentandola):
Posto** creaSala(){
Posto **v = (Posto **)calloc(numerofile, sizeof(Posto*));
assert(v != NULL);
int fila;
int posto;
Posto *seat;
for (fila = 0; fila<numerofile; fila++){
*(v + fila) = (Posto *)calloc(postixfila, sizeof(Posto));
assert(*(v + fila) != NULL);
for (posto = 0; posto<postixfila; posto++){
//seat = nuovoPosto(posto + 1, fila + 1);
//v[fila][posto] = *seat;
//free(seat);
}
}
return v;
}
Siccome calloc() inizializza la memoria a zero, dovresti stampare una serie di posti/file a zero, ma l'importante e' capire se arrivi fino alla fine in questo modo....
ALTRA COSA: aspetta a fare la distruggiSala(), commenta anche quella. Vediamo se si arriva in fondo, prima.
Davvero strano, anche perche' a me continua a funzionare.
C'e' un altro errore minore:
printf("--- Fila numero %d --- \n", numfila + 1);
numfila in quel momento non e' inizializzato, quindi questa istruzione non e' corretta, puoi sostituirla con
printf("--- Fila numero %d --- \n", fila + 1);
Tornando alle cose serie: sembra che ci sia bisogno di un esorcista.
Sarebbe opportuno provare ad escludere delle parti per vedere se almeno si arriva alla fine. Il programma pero' e' gia' piuttosto scarno, non so cosa si possa escludere.
Proverei escludendo l'inizializzazione (i.e. commentandola):
Posto** creaSala(){
Posto **v = (Posto **)calloc(numerofile, sizeof(Posto*));
assert(v != NULL);
int fila;
int posto;
Posto *seat;
for (fila = 0; fila<numerofile; fila++){
*(v + fila) = (Posto *)calloc(postixfila, sizeof(Posto));
assert(*(v + fila) != NULL);
for (posto = 0; posto<postixfila; posto++){
//seat = nuovoPosto(posto + 1, fila + 1);
//v[fila][posto] = *seat;
//free(seat);
}
}
return v;
}
Siccome calloc() inizializza la memoria a zero, dovresti stampare una serie di posti/file a zero, ma l'importante e' capire se arrivi fino alla fine in questo modo....
ALTRA COSA: aspetta a fare la distruggiSala(), commenta anche quella. Vediamo se si arriva in fondo, prima.
Ho provato a fare tutto quello che dici.
Commentando l'inizializzazione, stampa tutti 0 ma si interrompe comunque.
Togliendo distruggiSala() non cambia nulla (oltre all'ovvio memory leak).
A questo punto direi che è un problema (o magari un'impostazione) dell'IDE.
Provo a farlo runnare sulla macchina virtuale con ubuntu del portatile , vediamo cosa succede.
Male che vada, cambio ambiente
sottovento
10-05-2016, 13:29
Ho provato a fare tutto quello che dici.
Commentando l'inizializzazione, stampa tutti 0 ma si interrompe comunque.
Togliendo distruggiSala() non cambia nulla (oltre all'ovvio memory leak).
A questo punto direi che è un problema (o magari un'impostazione) dell'IDE.
Provo a farlo runnare sulla macchina virtuale con ubuntu del portatile , vediamo cosa succede.
Male che vada, cambio ambiente
Prova a togliere ancora qualcosa, magari nella stampa. Sarebbe interessante capire cosa succede. Chissa', magari ha ragione lui e ci sta sfuggendo qualcosa.
Per esempio, cambia la stampa:
void stampaSala(Posto **sala){
int fila;
int posto;
int numposto;
int numfila;
Posto *temp;
for (fila = 0; fila<numerofile; fila++){
//printf("--- Fila numero %d --- \n", numfila + 1); originale
printf("--- Fila numero %d --- \n", fila + 1);
for (posto = 0; posto<postixfila; posto++){
temp = &sala[fila][posto];
// numposto = getnumposto(temp);
// numfila = getnumfila(temp);
numposto = temp->numposto;
numfila = temp->numfila;
printf("numero di fila: %d \n", numfila);
printf("numero di posto: %d \n", numposto);
// if (temp->occupato == false){
// printf("il posto e' libero \n\n");
// }
}
}
}
se anche cosi' non arriva alla fine, prova a commentare anche numfila e numposto, inizializzandoli PRIMA del ciclo. A questo punto se continua a terminare in maniera abnorme, lascerei perdere quell'ambiente.
Altra cosa: incrementa il livello dei warning fino al massimo, cioe' al livello piu' pedante possibile, cosi' da avere piu' informazioni su quanto sta succedendo...
Prova a togliere ancora qualcosa, magari nella stampa. Sarebbe interessante capire cosa succede. Chissa', magari ha ragione lui e ci sta sfuggendo qualcosa.
Per esempio, cambia la stampa:
void stampaSala(Posto **sala){
int fila;
int posto;
int numposto;
int numfila;
Posto *temp;
for (fila = 0; fila<numerofile; fila++){
//printf("--- Fila numero %d --- \n", numfila + 1); originale
printf("--- Fila numero %d --- \n", fila + 1);
for (posto = 0; posto<postixfila; posto++){
temp = &sala[fila][posto];
// numposto = getnumposto(temp);
// numfila = getnumfila(temp);
numposto = temp->numposto;
numfila = temp->numfila;
printf("numero di fila: %d \n", numfila);
printf("numero di posto: %d \n", numposto);
// if (temp->occupato == false){
// printf("il posto e' libero \n\n");
// }
}
}
}
se anche cosi' non arriva alla fine, prova a commentare anche numfila e numposto, inizializzandoli PRIMA del ciclo. A questo punto se continua a terminare in maniera abnorme, lascerei perdere quell'ambiente.
Altra cosa: incrementa il livello dei warning fino al massimo, cioe' al livello piu' pedante possibile, cosi' da avere piu' informazioni su quanto sta succedendo...
Ho provato tutto, ma non c'è niente da fare.
Nessun warning compilando con -Wall.
Oggi pomeriggio cercherò un altro ide su cui emigrare :(
In ogni caso, grazie mille !
Volutomitra
10-05-2016, 20:15
Butto li una cosa a caso, non uccidetemi :fagiano:
E se fosse solo un semplice problema di flush dello standard output?
Butto li una cosa a caso, non uccidetemi :fagiano:
E se fosse solo un semplice problema di flush dello standard output?
Ti ringrazio per l'interessamento, ma ormai ho desistito :asd:
Sto su Eclipse e per ora va tutto bene !
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.