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
Ho fatto anche le verifiche sui puntatori degli array che hanno confermato la mia ipotesi.
Volevo sapere se è possibile che questo problema sia generato da errori di codice, oppure da un bug, piuttosto insidioso, di XCode.