Sistemi di Calcolo

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2017-2018

HomePage | Avvisi | Diario lezioni | Programma | Materiale didattico | Esami | Forum | Login

Revision [2979]

Last edited on 2017-10-04 19:14:04 by EmilioCoppa
Additions:
(gdb) finish // esegue fino al termine della funzione corrente


Revision [1822]

Edited on 2016-10-12 16:53:52 by EmilioCoppa
Additions:
Le soluzioni dell'esercitazione sono disponibili a questa [[SolEserc01AA1617 pagina]].
Deletions:
Le soluzione dell'esercitazioni sono disponibili a questa [[SolEserc01AA1617 pagina]].


Revision [1821]

Edited on 2016-10-12 16:53:20 by EmilioCoppa
Additions:
== Soluzioni ==
Le soluzione dell'esercitazioni sono disponibili a questa [[SolEserc01AA1617 pagina]].


Revision [1732]

Edited on 2016-10-06 20:01:58 by DanieleDelia
Additions:
Creare una directory di lavoro ##sc1617## e posizionarsi nella directory creata come segue:
Promemoria su ##gdb##:
%%(c)
(gdb) file // per caricare un eseguibile
(gdb) run [ ...] // per lanciare l'esecuzione con eventuali argomenti
(gdb) quit // per uscire da gdb (o CTRL-d)
(gdb) break mio_file.c:20 // inserisco un breakpoint alla linea 20 di mio_file.c
(gdb) break mio_file.c:20 if x == 0 // breakpoint condizionale
(gdb) info break // per mostrare breakpoint attivi
(gdb) cont // per riprendere l'esecuzione normalmente dopo un breakpoint
(gdb) step // prosegue l'esecuzione di una singola istruzione
(gdb) print x // stampa il contenuto della variabile x nello stack frame corrente
(gdb) clear mio_file.c:20 // per eliminare breakpoint su una locazione di riferimento
(gdb) delete 1 // per eliminare il breakpoint contrassegnato come 1 da 'info break'
Deletions:
Creare una **directory di lavoro** ##sc1617## e posizionarsi nella directory creata come segue:


Revision [1731]

Edited on 2016-10-06 19:55:13 by DanieleDelia
Additions:
I due metodi ##fib## e ##fib_iter## sono stati presi da Wikibooks ma restituiscono risultati difformi. Risalire alla causa di questa difformità con l'ausilio di ##gdb##, in particolare utilizzando breakpoint (possibilmente condizionali) per ispezionare il comportamento di ##fib_iter## e modificarne di conseguenza il codice per riallinearlo a quello di ##fib##.
Deletions:
I due metodi #fib# e #fib_iter# sono stati presi da Wikibooks ma restituiscono risultati difformi. Risalire alla causa di questa difformità con l'ausilio di #gdb#, in particolare utilizzando breakpoint (possibilmente condizionali) per ispezionare il comportamento di #fib_iter# e modificarne di conseguenza il codice per riallinearlo a quello di #fib#.


Revision [1730]

Edited on 2016-10-06 19:54:37 by DanieleDelia
Additions:
Il frammento di codice seguente calcola l'i-esimo numero della [[https://it.wikipedia.org/wiki/Successione_di_Fibonacci successione di Fibonacci]] specificato dall'utente. In particolare, esegue una implementazione ricorsiva ed una variante iterativa dell'algoritmo di calcolo:
%%(c;fibonacci.c)
// https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Fibonacci_Number_Program#Recursive_version
unsigned int fib(unsigned int n) {
if (n < 2) return n;
else return fib(n - 1) + fib(n - 2);
// https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Fibonacci_Number_Program#Iterative_version
unsigned int fib_iter(unsigned int n) {
unsigned int i = 0, j = 1, k, t;
for (k = 1; k <= n; ++k) {
t = i + j;
i = j;
j = t;
return j;
printf("Syntax: %s \n", argv[0]);
unsigned int n = atoi(argv[1]);
printf("[%u] ric: %u iter: %u\n", n, fib(n), fib_iter(n));
I due metodi #fib# e #fib_iter# sono stati presi da Wikibooks ma restituiscono risultati difformi. Risalire alla causa di questa difformità con l'ausilio di #gdb#, in particolare utilizzando breakpoint (possibilmente condizionali) per ispezionare il comportamento di #fib_iter# e modificarne di conseguenza il codice per riallinearlo a quello di #fib#.


Revision [1729]

Edited on 2016-10-06 19:45:17 by DanieleDelia
Additions:
== Esercizio 3 (manipolazione di stringhe) ==
Il seguente programma manipola una stringa in input mettendo ogni lettera al suo interno in lowercase:
%%(c;tolower.c)
#include
char* to_lower (const char *str) {
char* l = strdup(str);
char* c;
for (c = l; *c; c++) {
if (isupper(*c))
*c = tolower(*c);
}
return l;
int main (int argc, char* argv[])
{
if (argc != 2) return 1;
char* lower = to_lower (argv[1]);
while (*lower)
printf("%c", (*(lower++)));
printf("\n");
Quali errori sono presenti al suo interno?
== Esercizio 4 (navigazione nell'Atlantico) ==
Il codice seguente è stato adattato da un programma che simula l'avanzamento dell'RMS Titanic nell'Oceano Atlantico:
%%(c;boat.c)
#include
#define BOAT_SPEED 1
char* full_steam_ahead(unsigned current_distance) {
unsigned new_distance = current_distance + BOAT_SPEED;
char* log_text_suffix = "miles, go ahead!\n";
int buffer_length = strlen("log_text_suffix") + 3;
char* buffer;
sprintf(buffer, "%u %s", new_distance, log_text_suffix);
return buffer;
int main(int argc, char* argv[]) {
int to_the_atlantic;
int nautical_miles;
// check number of arguments
if (argc < 2) {
printf("Syntax: %s \n", argv[0]);
return 1;
}
// parse argv[1]'s content as an int using atoi()
to_the_atlantic = atoi(argv[1]);
if (to_the_atlantic < 1) {
printf("Specify a positive (non-zero) amount!\n");
return 1;
}
// advance the boat towards the Atlantic as requested by the user
char* captains_log;
for (nautical_miles = 1; nautical_miles <= to_the_atlantic; nautical_miles++) {
captains_log = full_steam_ahead(nautical_miles);
printf("%s", captains_log);
}
free(captains_log);
Al suo interno sono presenti un certo numero di bug identificabili tramite esecuzione sotto ##valgrind##. Individuarli utilizzando più valori di input (#argv[1]# conterrà il numero di miglia marine da percorrere) e correggerli.
== Esercizio 5 (liste collegate) ==
Di seguito è riportata una implementazione buggata di una lista collegata in C:
%%(c;list.c)
#include
typedef struct node {
char * id;
char * value;
struct node * next;
} node_t;
static int count = 0;
node_t* add_node(node_t* l, char* value) {
node_t* node = malloc(sizeof(node_t));
char id[16];
sprintf(id, "ID_%d", count++);
node->id = id;
node->value = value;
if (l != NULL)
node->next = l;

return node;
void print_list(node_t* head) {
node_t* current = head;
while (current != NULL) {
printf("%s\n", current->value);
current = current->next;
}
void delete_list(node_t * head) {
node_t* current = head;
while (current != NULL) {
free(current);
free(current->value);
current = current->next;
}
node_t* l;
l = add_node(NULL, "Hello");
l = add_node(l, " ");
l = add_node(l, "World");
l = add_node(NULL, "!");
print_list(l);
delete_list(l);
Individuare gli errori con l'ausilio di ##valgrind## e proporre una soluzione che utilizzi correttamente la memoria.
== Esercizio 6 (debugging in gdb) ==


Revision [1728]

Edited on 2016-10-06 19:10:11 by DanieleDelia
Additions:
printf("Final string: |%s|", s2);
Per scoprire cosa fanno le funzioni ##strcpy##, ##sprintf## e ##strcat## consultare la sezione 3 del manuale in linea (ad esempio, ##man 3 strcat##). Compilare ed eseguire il programma come per l'Esercizio 1: che tipo di errore si verifica? Proporre una soluzione al problema.
Deletions:
printf("Final destination string : |%s|", dest);


Revision [1727]

Edited on 2016-10-06 19:05:59 by DanieleDelia
Additions:
== Esercizio 1 (duplicazione di stringhe) ==
== Esercizio 2 (concatenazione di stringhe) ==
Il seguente frammento di codice può portare ad una corruzione dell'immagine di memoria di un processo:
%%(c;strcat.c)
#define BUFLEN 16
int main() {
char s1[BUFLEN], s2[BUFLEN];
strcpy(s1, "This is source");
sprintf(s2, "%s", "This is destination");
strcat(s2, s1);
printf("Final destination string : |%s|", dest);
Deletions:
== Esercizio 1 ==


Revision [1726]

Edited on 2016-10-06 18:59:42 by DanieleDelia
Additions:
Compilare il programma includendo le informazioni di debugging, quindi farlo eseguire all'interno ##valgrind##.
Che tipologia di errore viene riportato? Correggerlo, quindi rieseguire nuovamente il programma usando ##valgrind##.
Deletions:
Compilare il programma includendo le informazioni di debugging, quindi farlo girare utilizzando ##valgrind##.
Che tipologia di errore viene riportato? Correggerlo, quindi rieseguire nuovamente il programma sotto ##valgrind##.


Revision [1725]

Edited on 2016-10-06 18:59:21 by DanieleDelia
Additions:
L'obiettivo di questo esercizio è individuare e correggere un errore comune nell'utilizzo di funzioni di libreria C. Si immetta il seguente programma di esempio nel file ##strdup.c##:
Deletions:
L'obiettivo di questo esercizio è correggere nel seguente codice un errore comune nell'utilizzo di funzioni di libreria C. Si immetta il seguente programma di esempio nel file ##strdup.c##:


Revision [1724]

Edited on 2016-10-06 18:58:31 by DanieleDelia

No differences.

Revision [1723]

Edited on 2016-10-06 18:58:23 by DanieleDelia

No differences.

Revision [1722]

Edited on 2016-10-06 18:58:11 by DanieleDelia
Additions:
L'obiettivo di questo esercizio è correggere nel seguente codice un errore comune nell'utilizzo di funzioni di libreria C. Si immetta il seguente programma di esempio nel file ##strdup.c##:
int main (int argc, char* argv[]) {
char* prog_name = strdup(argv[0]);
Compilare il programma includendo le informazioni di debugging, quindi farlo girare utilizzando ##valgrind##.
$ gcc -g -o strdup strdup.c
$ valgrind ./strdup
Che tipologia di errore viene riportato? Correggerlo, quindi rieseguire nuovamente il programma sotto ##valgrind##.
Deletions:
int main (int argc, char *argv[]) {
char * prog_name = strdup(argv[0]);


Revision [1721]

The oldest known version of this page was created on 2016-10-06 18:54:07 by DanieleDelia
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by WikkaWiki
Page was generated in 0.0458 seconds