Entrambe le parti precedenti la revisioneRevisione precedenteProssima revisione | Revisione precedente |
informatica:sol:laboratorio17:esercitazionib:esercitazione2 [24/02/2017 alle 18:47 (8 anni fa)] – [Esercizio 1: tokenizer] Massimo Torquati | informatica:sol:laboratorio17:esercitazionib:esercitazione2 [08/03/2017 alle 15:38 (8 anni fa)] (versione attuale) – [Esercizio 5: libtokenizer.a] Massimo Torquati |
---|
| |
| |
===== Esercizio 1: funzioni rientranti ===== | ===== Esercizio 1: funzioni rientranti (tokenizer_r) ===== |
| |
Si consideri il seguente programma: | Si consideri il seguente programma: |
| |
Cosa c'e' che non va? Come si puo' correggere ? | Cosa c'e' che non va? Come si puo' correggere ? |
| (Suggerimento: leggere con attenzione il ''man'' di ''strtok''). |
| |
===== Esercizio 2: tokenizer_r ===== | NOTA: se si utilizza l'opzione ''-std=c99'', per evitare i warnings del tipo "implicit declaration of function X" aggiungere la seguente opzione di compilazione "-D_POSIX_C_SOURCE=200112L", oppure inserire la seguente define **prima del primo include**: |
| <code> |
Scrivere una seconda versione del programma precedente che implementa la funzione 'tokenizer_r' che ha la stessa identica interfaccia, ma che utilizza al suo interno ''strtok_r'' invece di ''strtok''. Quali sono le principali differenze tra 'tokenizer' e 'tokenizer_r' ? (Suggerimento: leggere con attenzione il ''man'' di ''strtok_r''). | #define _POSIX_C_SOURCE 200112L |
| </code> |
| |
NOTA: se si utilizza l'opzione ''-std=c99'', per evitare i warnings del tipo ''implicit declaration of function 'strtok_r'...'' aggiungere la seguente opzione di compilazione ''-D_POSIX_C_SOURCE=200112L''. La funzione strtok_r fa parte dello standard POSIX-2001. | ===== Esercizio 2: numeri random ===== |
| |
===== Esercizio 3: numeri random ===== | |
| |
Generare ''N'' numeri casuali interi nell'intervallo ''[0,K['' utilizzando le funzioni ''rand_r()'' ed ''srand()''. N e K sono definiti con delle opportune ''#define''. Calcolare il numero di occorrenze ''c_i'' di ciascun intero ''i'' nell'intervallo ''[0,K[''e stamparle sullo standard output. | Generare ''N'' numeri casuali interi nell'intervallo ''[0,K['' utilizzando le funzioni ''rand_r()'' ed ''srand()''. N e K sono definiti con delle opportune ''#define''. Calcolare il numero di occorrenze ''c_i'' di ciascun intero ''i'' nell'intervallo ''[0,K[''e stamparle sullo standard output. |
===== Esercizio 4: tokenizer_rfile ===== | |
| ===== Esercizio 3: tokenizer_rfile ===== |
| |
Scrivere un programma C che prende in input 3 argomenti, i primi due argomenti sono obbligatori, il terzo e' opzionale. Il primo argomento è il nome di un file di input in formato testuale contenente stringhe di parole. Ogni stringa ha una lunghezza massima pari a 1024 caratteri. Il secondo argomento corrisponde ad un file testuale di output che dovra' contenere tutte le parole del primo file, scritte al contrario una per ogni riga. Se il file di input non esiste, il programma dovrà ritornare un messaggio di errore opportuno sullo standard error (stderr). Se il file di output esiste gia', questo dovra' essere sovrascritto se il terzo argomento del programma o non è stato specificato oppure se tale argomento è diverso dal carattere 'a'. Se il terzo argomento è uguale al carattere 'a' l'output del programma dovrà essere appeso in fondo al file. | Scrivere un programma C che prende in input 3 argomenti, i primi due argomenti sono obbligatori, il terzo e' opzionale. Il primo argomento è il nome di un file di input in formato testuale contenente stringhe di parole. Ogni stringa ha una lunghezza massima pari a 1024 caratteri. Il secondo argomento corrisponde ad un file testuale di output che dovra' contenere tutte le parole del primo file, scritte al contrario una per ogni riga. Se il file di input non esiste, il programma dovrà ritornare un messaggio di errore opportuno sullo standard error (stderr). Se il file di output esiste gia', questo dovra' essere sovrascritto se il terzo argomento del programma o non è stato specificato oppure se tale argomento è diverso dal carattere 'a'. Se il terzo argomento è uguale al carattere 'a' l'output del programma dovrà essere appeso in fondo al file. |
| |
===== Esercizio 5: valgrind ===== | Suggerimento: per leggere righe del file di input utilizzare ''fgets'' (''man 3 fgets''), per scrivere righe sul file di output utilizzare ''fprintf''. |
| |
Verificare la correttezza degli accessi in memoria utilizzando ''valgrind'' del programma realizzato nell'esercizio 4. Verificare che non ci siano memory leaks all'uscita del programma. | ===== Esercizio 4: valgrind ===== |
| |
| Verificare la correttezza degli accessi in memoria utilizzando ''valgrind'' del programma realizzato nell'esercizio 3. Verificare che non ci siano memory leaks all'uscita del programma. |
| |
Valgrind permette, fra l'altro, di capire se le variabili sono inizializzate prima del loro uso, se accediamo a memoria gia' deallocata o mai allocata o a zone non inizializzate. | Valgrind permette, fra l'altro, di capire se le variabili sono inizializzate prima del loro uso, se accediamo a memoria gia' deallocata o mai allocata o a zone non inizializzate. |
Se si specifica l'opzione ''--leak-check=full'' (attenzione al doppio trattino), valgrind fornirà dettagli per ogni blocco di memoria che non è più raggiungibile o che pur essendo raggiungibile non è stato liberato, dando anche l'informazione di dove il blocco è stato allocato. | Se si specifica l'opzione ''--leak-check=full'' (attenzione al doppio trattino), valgrind fornirà dettagli per ogni blocco di memoria che non è più raggiungibile o che pur essendo raggiungibile non è stato liberato, dando anche l'informazione di dove il blocco è stato allocato. |
| |
===== Esercizio 6: libtokenizer.a ===== | ===== Esercizio 5: libtokenizer.a ===== |
| |
| Inserire nel file 'tokenizer.h' l'interfaccia di due funzioni 'tokenizer' e 'tokenizer_r' (quest'ultima e' quella implementata nell'esercizio 1 mentre tokenizer ha la stessa interfaccia di tokenizer_r ma usa strtok invece di strtok_r). Inserire nel file 'tokenizer.c' l'implementazione delle due funzioni. Creare quindi una librerie statica 'libtokenizer.a' e riscrivere il programma dell'esercizio 2 in modo che il programma main includa il file 'tokenizer.h' e linki la libreria 'libtokenizer.a'. |
| |
Inserire nel file 'tokenizer.h' l'interfaccia delle due funzioni 'tokenizer' e 'tokenizer_r' come descritte negli esercizi 1 e 2. Inserire nel file 'tokenizer.c' l'implementazione delle due funzioni. Creare quindi una librerie statica 'libtokenizer.a' e riscrivere il programma dell'esercizio 2 in modo che il programma main includa il file 'tokenizer.h' e linki la libreria. | ===== Esercizio 6: libtokenizer.so ===== |
| |
| Rifare l'esercizio 5 creando invece che una libreria statica una libreria dinamica ('libtokenizer.so'). |
| |
| |
| |