Download TD : Les fichiers sous UNIX, niveau utilisateur

Transcript
TD : Les fichiers sous UNIX, niveau utilisateur
Objectifs : Types de fichiers et de répertoires sous UNIX. Droits d’accès. Fichiers
et périphériques. Lien physique et lien symbolique. Redirection des entréessorties.
Exercice 1 : Redirection des entrées et sorties standards.
•
•
•
Redirigez la sortie de la commande ls –l vers un fichier quelconque.
Concaténez à ce fichier le résultat de la commande ps –ef.
Recherchez dans ce fichier toutes les lignes contenant votre nom en
redirigeant l’entrée.
Exercice 2 : Types de fichiers, fichiers spéciaux périphériques
•
•
•
•
Il existe différents types de fichier sous UNIX, découvrez les en utilisant la
commande ls –l dans votre répertoire et dans les répertoires /dev et /usr/bin
Listez le répertoire /dev et faites un ps, que remarquez vous, qu’en déduisez
vous ?
Ouvrez une autre console et essayer d'afficher le résultat d'une commande
sur l'autre console
Essayez d’écrire directement sur la console de la machine voisine. Quel est le
problème? Demandez à votre voisin de le résoudre.
Exercice 3 : Droits d’accès aux fichiers, aux répertoires
•
Créez un fichier quelconque de nom essai1 qui contiendra les trois
commandes suivantes:
ls
echo bonjour
ps
Essayez d'exécuter ce fichier de commandes. Quel est le problème?
Quels sont les droits par défaut du propriétaire, du groupe et du reste du
monde.
Rendez le fichier essai1 exécutable pour le propriétaire, le groupe et le reste
du monde. Exécutez le
fichier essai1.
• Créez un répertoire essairep. Quels sont les droits par défaut.
•
Ce répertoire est un répertoire privé. Vous ne voulez pas que les membres du
groupe ni le reste du monde puissent lister les fichiers ni écrire dans ce
répertoire mais qu'ils puissent y accéder. Vérifiez les droits et modifiez les si
nécessaire.
•
Vérifiez les droits de votre répertoire de travail et donnez l'autorisation au
1
groupe et au reste du monde d'y accéder.
•
Créez un fichier essai2 dans ce répertoire, vérifiez que le groupe et le reste du
monde ont le droit de lecture ou modifiez les droits sinon.
•
Vérifiez le résultat: votre binôme (ou voisin) peut-il lister les fichiers du
répertoire essairep, afficher le contenu du fichier essai2 de ce répertoire ou
copier ce fichier sur son compte ?
•
Finalement le répertoire est tellement confidentiel que vous ne voulez pas
que le groupe et le reste du monde puisse y accéder. Modifiez les droits en
conséquence et demander à votre binôme de vérifier le résultat.
•
Créez un autre répertoire essaid2 et donnez des droits de lecture et des droits
d’accès au répertoire mais aucun droit d’écriture au groupe et au reste du
monde.
•
Créez un fichier essai3 dans ce répertoire et donnez des droits en écriture au
fichier au groupe. Demandez à un membre du groupe d’essayer de modifier le
fichier, puis d’effacer le fichier. Expliquez.
•
Finalement vous voulez que par défaut, tout nouveau fichier créé ait un droit
en lecture et en écriture pour le propriétaire, un droit en lecture pour le
groupe et aucun droit pour les autres, et que tout nouveau répertoire ait un
droit d’accès au répertoire pour tout le monde, un droit d’accès en lecture et
en écriture pour le propriétaire et un droit en lecture pour le groupe.
Exercice 4 : Liens sur un fichier
•
Créez un répertoire essailn et placez-y un fichier quelconque essai. Créez
quatre liens différents lessai1, lessai2, lessai3, lessai4 sur essai dans essailn
(commande ln). Faites un ls –il, que remarquez vous ?
•
Changez les droits d’accès de lessai1, faites un ls –l, qu’en déduisez-vous ?
•
Quel est la taille de chacun des ces fichiers (utilisez la commande du), quel
est l’espace occupé par le répertoire ?
•
Détruire lessai3, faites un ls –il, expliquez.
•
Détruire essai, faites un ls –il, expliquez.
•
Créez un lien essai6 de votre répertoire de connexion vers essailn/lessai2.
•
Supprimez tous les droits pour vous, le groupe et les autres sur le répertoire
essailn.
•
Essayez d’afficher le contenu de essai6, et de le modifier en écriture. Qu’en
déduisez vous ?
•
A quoi peut servir les liens d’après vous ?
•
A l’aide de la commande df, visualiser les différents systèmes de fichier et
leur point de montage.
•
Repérez votre système de fichier et essayer de faire un lien vers un fichier
2
d’un autre système de fichier. Qu’en déduisez vous ?
•
Essayez à nouveau en utilisant l’option –s de ln. Faites un ls –il. Que
remarquez vous. Expliquez.
TD : Interpréteur de commandes
Objectif: Comprendre le travail de l'interpréteur et des fichiers d'initialisation.
Exercice 1: mini-interpréteur.
Question 1 : écrire un interpréteur.
•
•
•
Ecrire un programme qui simule un interpréteur de commandes. Il doit lire
une commande en entrée, l'interpréter et boucler ainsi jusqu'à la commande
quitter. Vous aurez besoin des fonctions C strstr, gets et strcmp.
Testez le avec différentes commandes (ls, cp, mkdir, etc.).
Essayez avec la commande cd. Que se passe-t-il? Expliquez?
Question 2: Quelques commandes internes.
•
Modifiez votre programme afin de définir quelques commandes internes (cd,
lrep qui liste uniquement les répertoires ou lcache qui ne liste que les fichiers
cachés). Pour cd vous aurez besoin de la fonction C chdir.
Exercice 2: Etude des fichiers d'initialisation.
•
•
•
•
•
•
•
Editez vos fichiers .tcshrc et .bashrc. Le fichier .tcshrc est le fichier
d'initialisation de l'interpréteur tcsh (un cshell amélioré) et .bashrc celui du
bash (un bourne shell amélioré) Expliquez ce qu'ils contiennent.
On veut simuler quelques commandes DOS sous unix: type, md, copy, cd..,
rename, del. Donnez les commandes qui permettent de le faire.
Modifiez votre .tcshrc pour que ces commandes soient utilisables dès la
connexion.
Personnalisez votre prompt pour qu’à chaque exécution de tcsh le prompt soit
sous la forme nommachine:nomutilisateur>
Créez un répertoire mesbin dans votre répertoire de travail. Copiez-y le
programme exécutable interpreteur de l'exercice 1 et faites en sorte qu’à
chaque fois que vous exécutez un tcsh, quelque soit le répertoire où vous
vous trouvez vous puissiez exécuter ce fichier.
Vous voulez maintenant qu'à chaque exécution de tcsh s'affichent la date du
jour, l'heure et la liste des utilisateurs qui sont connectés.
Finalement il est préférable de détruire les fichiers core à la sortie d’une
3
session. Faites en sorte qu’à chaque fois que vous quittez une session tous les
fichiers core de votre compte soient détruits. Pour le tester, créez quelques
fichiers core dans vos répertoires, faites un telnet sur votre propre machine
puis un logout.
TD: les processus, niveau utilisateur
Objectifs : découvrir et comprendre la notion de processus (existence, état, processus
père et fils). Etudier quelques commandes de base de gestion de processus. Voir les
liens entre processus et programmation (en C).
Question 1.
Exécutez la commande ps -ux. Quelle est la signification des champs USER, PID, TTY,
STAT, CMD?
Question 2.
Trouvez des options qui affichent tous les processus en format long avec le nom de
l'utilisateur propriétaire. Reprenez la commande précédente mais affichez uniquement
les processus qui vous appartiennent.
Question 3 .
Ecrivez un programme qui boucle à l’infini en affichant un message à l’écran.
Compilez le et exécutez le en avant plan puis arrêtez le par la commande clavier
CTRL+C.
Faites un ps, existe-t-il encore ? Si oui sous quel état ?
Exécutez à nouveau ce programme en avant plan et arrêtez le par la commande clavier
CTRL+Z.
Faites un ps, existe-t-il encore ? Si oui sous quel état ?
Relancez ce processus en avant plan.
Exécutez à nouveau ce programme en arrière plan.
Faites un ps pour trouver son état ?
Tuez enfin les processus qui restent associés à ce programme.
Question 4.
Sachant que la fonction c getpid() renvoie le PID du processus et que la fonction
getppid() renvoie le PID du processus père (le PPID), écrire un programme C qui affiche
le PID du processus ainsi que celui de son père.
Question 5.
Que fait d’après vous le programme suivant :
/*concur.c*/
#include<stdio.h>
void main()
{
int pid,i ;
4
pid = fork() ;
if (pid != 0)
for (i=0 ; i<10 ;i++) {printf(“\n je suis le processus père %d”,i ) ;
sleep(1) ;} ;
if (pid == 0)
for (i=0 ; i<10 ;i++) {printf(“\n je suis le processus fils %d”,i ) ;
sleep(1) ;} ;
}
Créez ce fichier, compilez le et exécutez-le en avant plan. Que remarquez vous ?
Relancez le et interrompez le. Tuez le processus fils et relancez le processus. Que
remarquez vous?
Modifiez le programme de la question 3 en ajoutant un sleep(2) dans la boucle.
Compilez puis exécutez ce programme et le programme concur en arrière plan.
Modifiez le programme concur.c de telle manière que le processus fils exécute le
programme de la question 3.
Modifiez à nouveau le programme concur.c pour faire exécuter au processus fils xeyes.
Une fois le processus père terminé faites un ps pour voir l'état du fils. Quel est son père
maintenant?
Question 6.
Combien de processus sont créés par le programme bidon.c suivant (sans compter celui
associé au programme bidon lui-même) ?
void main()
{
fork() ;
fork() ;
fork() ;
}
En déduire la formule générale.
5
TD : Scripts UNIX (2)
Objectif: Programmer en c-shell.
Cet exercice va vous permettre de gérer une poubelle.
Question 1: créer une poubelle
Ecrire un script qui créer le répertoire poubelle dans le répertoire de travail si il n'existe pas.
Question 2: "Détruire" un fichier
Modifier le script précédent de tel manière qu'il déplace le fichier qu'il reçoit en argument dans le répertoire poubelle.
Question 3: Une liste de fichier Modifier le script précédent en considérant qu'il peut recevoir une liste de fichier et non plus un fichier.
Question 4: Remplacer la commande rm
Faire en sorte qu'à chaque appel de rm c'est votre script qui soit appelé pour chaque exécution d'un cshell.
Question 5: Vider la poubelle
Ecrire un script qui permet de vider la poubelle. Rappel: le caractère \ permet d'appeler une commande sans tenir compte de l'alias. Par exemple:
alias ls ls -l | more
ls  c'est la commande ls ­l | more qui est exécutée
\ls  c'est la commande ls qui est exécutée
Question 6: L'option ­r Modifier le script précédent pour qu'il accepte l'option ­r qui va aussi déplacer récursivement tous les répertoires et sous répertoires dans le dossier poubelle. Dans cas le script accepte des répertoires en argument.
Question 7: L'option ­i Modifier le script précédent pour qu'il accepte l'option ­i qui demande confirmation à l'utilisateur avant de déplacer les fichiers.
Question 8: Récupérer les fichiers
Ecrire un script unrm qui donne la possibilité de sortir un fichier ou un répertoire de la poubelle dans un répertoire donné en paramètre.
Par exemple:
unrm fichier1 . va sortir le fichier fichier1 de la poubelle s'il existe pour le mettre dans le répertoire courant.
6
Question 9: La déclarer comme nouvelle commande
Copier vos scripts dans le répertoire bin de votre répertoire de travail et vérifiez que toutes vos commandes liés à la gestion de la poubelle sont accessibles de n'importe où. 7
TD : Scripts UNIX (1)
Objectif: Programmer en c-shell.
Exercice 1: Test sur les fichiers ou les répertoires
a. Ecrire un script qui vérifie l'existence dans le répertoire courant du fichier dont le nom est passé en paramètre. Attention, vérifiez avant le test que le paramètre est différent de "" ( $1 == "").
b. Ecrire un script qui vérifie que le nom passé en paramètre est un fichier ou un répertoire.
Exercice 2: Script de concaténation + tri de deux fichiers
a. Ecrire un script qui concatène (cat) puis trie (sort) deux fichiers file1 et file2 dans un nouveau fichier file3 et qui affiche le nombre total de lignes (wc ­l). Les noms des trois fichiers doivent être passés en paramètre.
b. Modifier le script précédent pour que l'utilisateur soit obligé de saisir au clavier le (ou les) noms de fichiers qu'il aurait oubliés d'indiquer en lançant le script. Exercice 3: Application numérique
Faire un script qui propose un menu à l'utilisateur pour faire des opérations simples (addition, soustraction, division, multiplication) et qui affiche le résultat.
Exercice 4: Compléter le script suivant en faisant tous les tests nécessaires.
#!/bin/csh
clear
while(1)
echo "Menu"
echo "
Affichage répertoire courant
echo "
Liste des fihiers du répertoire
echo "
Informations sur un fichier
echo "
Changement de répertoire
echo "
n premiéres lignes d'un fichier
echo "
Sortie
echo ­n "Choix:
" set choix=$<
switch ($choix)
case 0: exit(0)
case 1: pwd; breaksw
case 2:
1"
2"
3"
4"
5"
0"
8
case 3:
case 4:
case 5: default: end
endsw
9
TD1 : Initiation aux commandes UNIX
Nous allons travailler sous LINUX, sous l'interpréteur de commandes bash (entre
un bourne-shell et un c-shell). Par ailleurs, vous pouvez travailler sous le c-shell
en tapant la commande csh ou tcsh.
• Commandes utilisateurs.
A l'aide du résumé des commandes et du cours et des indications données votre
chargé de TD:
• Afficher le nom du répertoire courant.
• Lister les fichiers et répertoires du répertoire /etc/
• Créer le sous répertoire textes dans le répertoire courant.
• Aller se placer dans textes.
• Y copier les fichiers /etc/hosts et /etc/inetd.conf.
• Afficher le fichier inetd.conf à l'écran page par page.
• Afficher uniquement les dix dernières lignes de inetd.conf.
• Afficher toutes les lignes de inetd.conf contenant la chaîne stream
• Afficher le fichier hosts en numérotant les lignes.
•
•
•
•
•
•
•
Sous quel nom êtes vous logué?
Quels sont tous les utilisateurs logués sur la même machine que vous?
Quels sont tous les utilisateurs logués sur le même réseau que vous?
Quel est le nom de la machine sur laquelle vous travaillez?
Quelles sont les différentes versions de l'exécutable emacs disponibles.
Laquelle est utilisée quand vous tapez emacs?
Comment obtenir un mode d'emploi en lignes d'emacs?
•
•
•
Afficher sans l'exécuter la dernière commande qui utilisait cp.
Lister les fichiers et catalogues de /usr/bin. Que contient ce répertoire?
Afficher tous les fichiers (y compris les fichiers cachés) et en format long
de votre répertoire de travail.
En déduire la convention adoptée par UNIX pour les fichiers cachés.
Tester cette convention en créant un fichier caché.
Lister uniquement les fichiers qui commencent par la dans /usr/bin.
Afficher les fichiers et catalogues du répertoire de travail de votre binôme,
y compris les fichiers cachés.
Afficher page par page le fichier .emacs du répertoire de travail de votre
binôme.
Essayer d'y détruire un fichier. Quel est le problème?
•
•
•
•
•
•
•
Commandes avancées
10
En une seule ligne de commande:
• Lister tous les fichiers dont les noms commencent par un caractère
alphabétique minuscule compris entre a et d (créez quelques fichiers
commençant par a,b,c ou d si vous n'en avez pas).
• Créer un fichier dont le nom commence par un point d'interrogation (?)
• Rediriger les résultats des commandes ls, last et ps dans le fichier toto.
• Lister tous les fichiers de /usr/bin dont les noms comportent exactement 4
caractères
• Afficher la date du jour sous la forme jj/mm/aa par la phrase suivante
"nous sommes le : jj/mm/aa"
•
Un premier programme
• Taper sous emacs le programme suivant:
/* Fichier bonjour.c */
#include <stdio.h>
main ()
{
printf ("Bonjour, j'utilise LINUX \n");
}
•
•
Compilez-le et exécutez-le.
Sachant que l'instruction C system(char*) permet d'exécuter une
commande système (ex: system("ls –l")), modifiez le programme ci-dessus
afin d'afficher le nom de la machine sur laquelle vous travaillez.
•
•
Aspects réseaux.
A l'aide de la commande df, étudiez le système de fichiers.
Qu'en déduisez-vous?
Où se trouve physiquement votre répertoire utilisateur?
• Visualiser le fichier /etc/fstab et faites le rapprochement avec le résultat de la
commande df. D'après vous à quoi sert ce fichier?
Exécutez la commande ifconfig. Quel est le problème?
Où se trouve la commande ifconfig?
Pourquoi n'avez vous pas pu l'exécuter? (visualiser la variable PATH).
Trouvez une solution pour finalement exécuter la commande ifconfig.
Quelle est votre adresse réseau (adresse IP), comparez la avec vos voisins.
Que représente d'après vous la HW adresse?
En repérant l'adresse IP de la machine de votre voisin, faites un ping n°IP ?
Connectez-vous sur la machine de votre voisin (commande ssh n°IP ou ssh
nom_machine).
Lister les fichiers du répertoire courant.
Où s'est exécutée cette commande?
Qu'en déduisez-vous?
De quel répertoire s'agit-il?
Qu'en déduisez-vous?
• Toujours connecté sur la machine du voisin, essayez de lancer l'éditeur de
texte xedit et la commande xeyes.
11
Que se passe-t-il?
TD : Les variables d'environnement
Objectif: Etudier un lien entre UNIX et C, les variables d'environnement.
Exercice 1: Afficher les variables d'environnement d'un programme C.
Ecrire un programme monenv.c qui affiche les variables d'environnement et leur
valeur.
Exercice 2: Un exemple d'utilisation des variables d'environnement.
On veut écrire un programme qui à partir d'un fichier texte qui contient des
rendez-vous et d'une date passée en argument, donne tous les rendez-vous de la
journée.
Pour cela, on vous donne la fonction search(char* nomDeFichier, char* date) qui
recherche les rendez-vous dans le fichier nomDeFichier pour la date date. Cette
fonction se trouve dans le fichier rdvSearch.c. Il vous reste donc à compléter la
fonction rdv.c dont l'objectif est de récupérer le nom du fichier qui contient les
rendez-vous et la date recherchée (initialisation de datafile et date).
L'utilisateur à plusieurs solutions pour indiquer le nom de son fichier de rendezvous: par variable d'environnement (question 2.1), par fichier caché (question
2.2) et enfin en le passant en argument de la commande (question 2.3).
Remarques:
• Les fichiers rdvSearch.c et rdv.c se trouve dans le répertoire
/home/users/TPINFO/coupey/varenv. Vous y trouverez aussi d'autres fichiers à
copier dont un exemple de fichier de rendez-vous (mesrdv).
• Vous aurez besoin des fonction C strcpy, getenv et strcat.
• Les rendez-vous sont notés sous forme de texte ascii, ils sont séparés par une
ligne blanche et la date est en tête de la ligne.
Exemple:
20/02/02 : Commission informatique
20/02/02 : Conseil d'institut
27/02/02 : Conseil de département
2.1. Compléter le programme principal sachant que le fichier de rendez-vous est
fixé par la variable d'environnement RENDEZVOUS. Si la variable
d'environnement n'est pas définie, le programme sort en erreur.
Par exemple:
> rendezvous 20/02/02
12
20/02/02 : Commission informatique
20/02/02 : Conseil d'institut
2.2. Si la variable RENDEZVOUS n'est pas définie, la seconde possibilité est de
considérer que le fichier de rendez-vous est $HOME/.rendez-vous. Compléter le
programme principal.
2.3. Enfin, la dernière possibilité considère que le fichier est passé en argument
du programme par l’option –f <nomdefichier>. Cette dernière possibilité sera
prioritaire sur les deux autres. Compléter le programme principal.
Par exemple:
> rendezvous -f ~/prive/agenda 28/03/02
28/03/02 : anniversaire de Pascal
ANNEXES
Fichier rdv.c à compléter:
#define MAINFILE
#include "rdv.h"
#include <stdlib.h>
/* char *getenv(char *name) renvoie un pointeur sur la valeur
(chaîne de
caractère) de la variable d'environnement name dans
l'environnement, NULL
si la variable n'est pas définie. Prototype dans stdlib.
*/
int main(int argc , char *argv[] , char *arge[]){
char * sptr, datafile[128] ;
int datepos ;
/* Recherche de la variable RENDEZVOUS dans l'environnement */
/*
à compléter
/* Si la variable d'environnement
de sa
valeur dans datafile[] */
/*
RENDEZVOUS est définie, copie
à compléter
/* Si la variable d'environnement
message
*/
*/
RENDEZVOUS n'est pas définie
13
d'erreur et sortie.
a modifier dans les versions 2 et 3 */
/*
à compléter
*/
/* Lecture du motif à rechercher, à modifier dans la version 3 */
if (argc == 2)
datepos = 1 ; /*En version 1 et 2, la date est dans argv[1] */
else {
printf("Usage %s jj:mm:aaaa\n",argv[0]); /* modifier en version
3*/
exit(2);}
/* c'est la 2eme fin en erreur */
/* Lancement de la recherche */
search(datafile, argv[datepos])
;
}
Fichier rdvSearch.c (à laisser tel quel):
#include "rdv.h"
/** int getline(FILE *fic, char *buffer) lit une ligne du fichier
fic et
l'écrit dans buffer. Le caractère de fin de ligne est remplacé par
'\0'.
La fonction renvoie le nombre de caracteres de la ligne y compris le
'\0'
final (une ligne vide renvoie donc 1). A la fin du fichier, la
fonction
ecrit une ligne vide dans buffer et renvoie 0 */
int getline(FILE* fic, char* buffer) {
int bufferindex=0;
char c,nl='\n';
for(c=getc(fic);c!=nl && c!=EOF;c=getc(fic))
buffer[bufferindex++]=c;
buffer[bufferindex]='\0';
if (bufferindex>0 || c==nl) return(bufferindex+1);
else return(0); /* EOF et aucun caractere n'a ete lu*/
}
/** void search(char* datafile, char* date) affiche tous les
paragraphes de datafile qui commencent par date. Deux paragraphes
sont separes par une ligne blanche. */
void search(char* datafile, char* date) {
14
char lineholder[512];
FILE *datafilehandle;
char *sptr;
int nbcharlus ;
/*ouverture du fichier*/
datafilehandle=fopen(datafile,"r");
if (datafilehandle==NULL) {
printf("le fichier %s n'est pas accessible en lecture\n",
datafile);
exit (3) ;
}
/* recherche des rendez-vous */
nbcharlus= getline(datafilehandle,lineholder);
while(nbcharlus>0)
{if ((sptr=strstr(lineholder,date))==lineholder) {/*date
reconnue*/
do{
/* on affiche le paragraphe */
printf("%s\n",lineholder);
nbcharlus= getline(datafilehandle,lineholder);
}while (nbcharlus>1);
printf("\n") ; /* la ligne entre deux paragraphes a mis fin
au
"do while" mais elle n'a pas encore été
affichée */
}/*fin du if */
nbcharlus= getline(datafilehandle,lineholder);
} /* fin du while */
/*fermer le fichier*/
fclose(datafilehandle);
}
Fichier rdv.h (à laisser tel quel):
#include <string.h>
#include <stdio.h>
#ifdef MAINFILE
#define EXTERN /* Effacer EXTERN dans le fichier principal */
#else
#define EXTERN extern
#endif
EXTERN char date[11] ; /* format jj/mm/aaaa*/
EXTERN char datafile[128]; 15
TD: Variables en mémoire
Objectifs : Comprendre le chargement en mémoire
Tous les programmes sont disponibles sous unix dans
/home/users/TPINFO/coupey/memoire
Question 1
Démarrez sous Linux. Copiez memoire.c et ouvrez-le sous emacs. Que fait ce
programme ? compilez le (make mémoire) et exécutez-le. Notez le résultat
avant le plantage:
Question 2: Emplacement et initialisation des tableaux.
Copiez tableaux.c. Lisez le code, puis exécutez-le. Notez les résultats :
Variabl portée durée de adresse
taille
valeur
Zone
e
vie
initiale
gtab1
gvar
gtab2
i (de
main)
j
ltab1
ltab2
ltptr
Question 3: Où sont le code et les variables?
Copiez adr_var_fon.c. Lisez le code, puis exécutez-le. Notez les résultats et
complétez quand vous pouvez :
Variabl
e
main
wher_v
ar
mi
mtab[0
]
i
tab[0]
ip
ptab0
portée
durée de
vie
adresse
taille
zone
Question 4: Taille maximale de la pile.
16
Copiez taille_pile.c. Lisez le code, expliquez ce qu'il fait. Essayez de prévoir
comment le programme s'arrete, puis exécutez-le. Notez les résultats.
Question 5: Allocation dynamique et désallocation.
Copiez allocFree.c. Lisez le code, expliquez ce qu'il fait. Exécutez-le. Etudiez le
résultat. Comment se fait la désallocation et la ré-allocation ? Quelle est la
différence d'adresse entre deux zones allouées successives ? Expliquez.
ANNEXES
Fichier memoire.c
#include <stdio.h>
#include <stdlib.h>
main() {
int i=0 ;
char* sptr ;
while ((sptr = malloc(1020)) != NULL)
{
printf("Nombre de kilo-octets consommés:%d \n", i);
i++;
}
printf("\nLa mémoire disponible est de %d kilo-octets\n" ,i);
getchar();
}
Fichier adr_tableaux.c
#include <stdio.h>
#define NL printf("\n")
void main();
void ecris(int*);
int gtab1[10],gvar;
int gtab2[10] = {10,11,12,13,14,15,16,17};
void main(){
/* Initialisation et affectation des tableaux*/
int i=2;
static int j;
int ltab1[10]={0,1,2,3,4,5,6,7,8,9}, ltab2[10], *ltptr;
printf("gtab1 : %p, gvar : %p, gtab2 : %p,"
"&i : %p, &j : %p, ltab1 : %p, ltab2 : %p, &ltptr :
%p, ltptr : %p\n",
gtab1, &gvar, gtab2, &i, &j, ltab1, ltab2, &ltptr,
17
ltptr);
ecris(gtab1);
ecris(gtab2);
ecris(ltab1);
ecris(ltab2);
getchar();
}
void ecris(int *tab){
int i=0;
while(i<10) printf("%4d
NL;
}
",tab[i++]);
Fichier adr_var_fonc.c
#include <stdio.h>
#include <stdlib.h>
#define NL printf("\n")
void main();
void where_var(int i, int tab[], int *ip, int *ptab);
void main(){
int mi=0;
int mtab[10];
where_var(mi,mtab,&mi,&mtab[0]);
getchar();
}
void where_var(int i, int tab[], int *ip, int *ptab0) {
printf("\nAdresses des variables et des fonctions :\n\n");
printf("fonctions: main: %p, where_var: %p", main, where_var);
NL;NL;
printf("variables locales de main : mi: %p, mtab[0]: %p",ip,ptab0)
;
NL;NL;
printf("parametres de where_var : i: %p, tab[0]: %p, ip : %p,
ptab0 : %p",&i, &tab[0], &ip, &ptab0) ;
NL;NL;
18
}
Fichier taille_pile.c
#include <stdio.h>
#include <stdlib.h>
void topstack(int n) {
char tab[1024] ;
/* Réserve 1 Ko sur la pile */
printf("%d : %p ",n, tab);
/* on indique le nombre de Ko
réservés */
topstack(n+1) ;
/* on recommence */
}
void main() {
topstack(1) ;
getchar();
}
/*
on
démarre la 1ere allocation */
Fichier allocFree.c
#include <stdio.h>
#include <stdlib.h>
void main() {
char* tabZone[50] ;
int i,j,r1,r2 ;
j=0 ;
while(j<42) {
printf("\nAlloue: ");
for (i=j ; i<j+8 ; i++) {
tabZone[i] = malloc(1024) ;
printf ("\t%d : %p",i,tabZone[i]);
}
j=i ;
r1=rand() % j;
19
do {
r2=rand() % j;
} while (r2 == r1) ;
printf("\nLibere : %d : %p\t%d : %p",
r1, tabZone[r1], r2, tabZone[r2]);
free(tabZone[r1]);
free(tabZone[r2]);
}
getchar();
}
20