|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jan 2013
Messaggi: 38
|
[C] Problema allocazione memoria dinamica (Risolto)
Buongiorno a tutti,
mi sono appena iscritto al forum per sapere da voi qualcosa in più riguardo ad un problema di esecuzione di un programma C. Il sorgente del programma in questione è il seguente Codice:
// // PROGRAMMA DI TIMING COUNTDOWN // Il programma riceve da linea di comando n-argomenti (interi) in secondi. // // Il programma fa il refresh dello schermo costante. // Visualizza nella prima riga il timer totale crescente e decrescente (somma di tutti i timing) // Nella seconda riga scorrono, uno dopo l'altro, gli altri timer, con visualizzazione crescente e descrescente. // // Il programma, inoltre, può acquisire attraverso il flag '-f' un file che contiene i timers, separati da un carattere spaziatore. (da sviluppare) // #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <unistd.h> // FUNCTIONS PROTOTIPES void print_error(); long int * timers_generate(const char * string_matrix[], int matrix_dim); int main(int argc, const char * argv[]) { // VARIABLE long int *timers, total, total_in, current, current_in; int i; total = total_in = current = current_in = i = 0; timers = NULL; // INIZIALIZE SCREEN system("clear"); // BODY SOURCE // // Checks numbers of argv: // - no timer: views manual // - > 1 timers: views countdown total and countdown current switch (argc) { case 1: // no args print_error(); break; default: // args > 1 timers = timers_generate(&argv[1], argc - 1); if (timers != NULL) { // Calcolo tempo totale for (i = 1; i < timers[0]; i++) total = total + timers[i]; // Visualizzo i timers i = 1; current = timers[i]; current_in = 0; while (total_in < total) { // contatore totale if (current_in == current && i < timers[0]) { // contatore parziale i++; current = timers[i]; current_in = 0; } printf("\t TIMER\n"); printf(" Total\t\t Current\n"); printf(" %02ld:%02ld\t\t %02ld:%02ld\n", total_in/60, total_in % 60, current_in/60, current_in % 60); printf("-%02ld:%02ld\t\t -%02ld:%02ld\n", (total-total_in)/60, (total-total_in) % 60, (current-current_in)/60, (current-current_in) % 60); if (i < timers[0]-1) { printf(" Next %02ld:%02ld\n", timers[i+1]/60, timers[i+1] % 60); } sleep(1); total_in++; current_in++; system("clear"); } printf("Time's up!\n\n"); } else print_error(); break; } } // FUNZIONE DI GENERAZIONE DELL'ARRAY CON I TIMERS // // Input: puntatore a matrice di stringhe con dimensione // Output: NULL se nessuna stringa è valida, puntatore se almeno 1 è valido (il primo valore del vettore corrisponde alla dimensione del vettore) long int * timers_generate(const char *string_matrix[], int matrix_dim){ // Variabili int i, j, is_correct, n_correct; i = j = 0; is_correct = 1; n_correct = -1; long int *work, *timer_array; work = timer_array = NULL; // Alloco massima memoria (pensando che tutti i valori siano validi) work = (long*)malloc(matrix_dim * sizeof(long)); if (work != NULL) { // allocazione corretta // inizializzo array for (i=0; i < matrix_dim; i++, work[i] = 0); // elaboro for (i = 0; i < matrix_dim; i++) { is_correct = 1; for (j = 0; j < strlen(string_matrix[i]) && is_correct; j++) { // 'strlen' viene sicuramente eseguita dato che la stringa non è nulla if (isdigit(string_matrix[i][j]) == 0) is_correct = 0; } if (is_correct) { // verifico se la stringa è valida n_correct++; // conto da 0 per comodità del vettore work[n_correct]=atol(string_matrix[i]); } } if (n_correct >= 0) { // valuto il return e ottimizzo l'array creato timer_array = (long*) malloc((n_correct+1+1) * sizeof(long)); // pongo in testa al vettore il numero di elementi presenti // 'n_correct' inizia a contare da 0, quindi gli elementi validi saranno 'n_correct + 1' if (timer_array != NULL) { // allocazione corretta // inizializzo il vettore for (i = 0; i < n_correct + 2; i++, timer_array[i] = 0); timer_array[0] = n_correct + 2; // salvo numero elemnti dell'array for (i = 1; i < n_correct + 2; i++) timer_array[i] = work [i-1]; // copiato l'array con il giusto numero di elementi free(work); // dealloco 'work' return timer_array; } else return NULL; } else return NULL; } else return NULL; } // FUNZIONE DI STAMPA DELLA GUIDA void print_error(){ printf("TIMER COUNTDOWN\n\n"); printf("Sintassi: Timer_Countdown time_s [time_s] [time_s] ....\n\n"); printf("Questo programma data una serie di tempi in secondi, fa il coundown sia dei singoli timer che del totale, visualizzando sia il tempo che avanza, sia quello rimanante\n\n\n"); } Ho postato tutto il codice per completezza, ma il problema è presente nelle istruzioni in grassetto. Inizio col dire che programmo con XCode 4.5.2 e il problema si presenta con entrambi i compilatori del programma (Apple e GCC). In sostanza la malloc alloca settori di memoria già precedentemente occupati da 'work'. Questo non si nota a prima vista, dato che il programma si esegue regolarmente, ma con il cambiamento dell'ultimo valore del vettore 'work' dovuto all'assegnazione di Codice:
timer_array[0] = n_correct + 2 Volevo sapere se è possibile che questo problema sia generato da errori di codice, oppure da un bug, piuttosto insidioso, di XCode. Ultima modifica di Spe! : 15-01-2013 alle 12:24. Motivo: Eliminazione commento |
![]() |
![]() |
![]() |
#2 |
Bannato
Iscritto dal: Dec 2012
Messaggi: 41
|
Mhh ho fatto un piccolo test .. su windows, anche se non dovrebbe cambiare niente (spero
![]() Apparte il fatto della chiamata system che non ho cambiato per pigrizia, inizialmente ho passato due parametri al programma, crash ovvio.. come si vede glie ne ho passati anche 3 tanto per.. però non crasha se con 1 parametro. Ora contando che sono sveglio come un albero.. secondo me devi controllare il passaggio dei parametri, forse è quello il problema. ![]() Spero di non aver detto una cessata ![]() ![]() |
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Jan 2013
Messaggi: 38
|
Grazie stohuman per aver provato a testare il codice.
Molto probabilmente il crash era dovuto alla chiusura improvvisa del programma, dato che mi era "sfuggito" un commento di troppo nel comando sleep(1) che scandiva la procedura. ![]() ![]() Corretto il codice, ma il problema dell'allocazione rimane. Ricordo di aver avuto problemi qualche tempo fa, con alcuni programmi che gestivano percorsi di files da linea da comando; non so però quanto questo possa incidere su semplici argomenti interi. EDIT: Risolto, mancava il numero dei bytes da allocare nella malloc! ![]() ![]() ![]() Ultima modifica di Spe! : 15-01-2013 alle 12:19. |
![]() |
![]() |
![]() |
#4 |
Bannato
Iscritto dal: Dec 2012
Messaggi: 41
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 03:22.