Chapitre 10 • Manipulations par octets
Cartouche
| Champ | Valeur |
|---|---|
| Auteur·e | Élise |
| Édition | 2024-02-05 |
| Taille des équipes | 1 personne |
| Rendu | via git, et dépôt $YEAR_pgc_c10, droits en lecture à delivery_collector |
| Compilation | via make avec règles all, clean, fclean, re |
| Nom du binaire | tests unitaires : ut.out |
Barème
| Critère | Points |
|---|---|
| memset & test | 3 |
| memcpy & test | 4 |
| arrset & test | 5 |
| memmove & test | 5 |
| Ajout des fonctions et des tests à la libstu | 3 |
| Total des critères | 20 |
| Note maximale | 20 |
Règlement
La réalisation de cet exercice est assujettie aux règles en vigueur dans l’école en matière de triche et de normalisation. Tricher vous expose à de graves sanctions.
Vous devez respecter les règles de normalisation suivantes : https://git.ecole-89.com/eriizu/coding_style/src/branch/main/norm.md
Le non-respect de la norme vous fera perdre une partie ou la totalité des points qui auraient pu être acquis, sur l’ensemble du rendu.
Instructions de rendu
Respectez à la lettre les noms de fichiers et leur emplacement dans le dépôt de rendu. S’il vous est demandé de rendre un fichier nommé hello.c sans qu’un nom de dossier soit précisé : rendez un fichier hello.c à la racine de votre dépôt.
La présence d’une étoile * signifie que le nom du fichier peut être n’importe lequel dès lors qu’il porte l’extension ou l’affixe (préfixe/suffixe) demandée. Elle signifie aussi qu’il est possible de rendre plusieurs fichiers.
La présence d’une double étoile ** signifie que les fichiers peuvent être placés n’importe où dans un dossier, y compris dans des sous-dossiers.
Pensez à faire des commits et des push fréquemment. Autrement nous ne pouvons pas vous aider à retrouver vos fichiers perdus.
Fonctions autorisées et interdites
Par défaut, toute fonction système (comme write) ou fonction des bibliothèques (comme printf ou puts) sont interdites.
À chaque exercice vous sera donné une liste de fonction autorisées, le cas échéant.
Tests unitaires
Vous devez rendre un fichier de test unitaire pour chaque fonctions demandée.
Correction du code source en C
Le ou les livrables de votre dépôt doivent compiler avec la commande make.
Votre Makefile doit absolument avoir les règles :
all;fclean;clean;re.
Avec le .PHONY approprié.
Synopsis
L’objectif du jour c’est que vous deveniez à l’aise avec les manipulations octets par octets. On va voir comment mettre à zéro toute une zone mémoire, comment copier une valeur de n’importe quelle taille d’une zone mémoire à une autre et comment initialiser un tableau de n’importe quel type d’élément avec une valuer par défaut.
Une fois que vous aurez écrit ces fonctions, vous pourrez les ajouter à votre bibliothèque stulib.
Exercice : memset
Fichiers à rendre : {src,test}/memset.c
*Fonctions autorisées : aucune
Implémentez la fonction suivante :
void *stu_memset(void *ptr, char byte, unsigned in n);
Son métier est de remplir la zone mémoire ptr avec la valeur byte et de s’arrêter après avoir rempli n octets.
Exemple d’utilisation :
unsigned int arr_sire;
int *array;
arr_size = sizeof(int) * 12;
array = malloc(arr_size);
stu_memset(array, 0, arr_size);
// array est maintenant rempli de 0
Exercice : memcpy
Fichiers à rendre : {src,test}/memcpy.c
*Fonctions autorisées : aucune
Implémentez la fonction suivante :
void *stu_memcpy(void *dest, const void *src, unsigned int n);
Elle doit copier n octets depuis la zone mémoire src vers la zone mémoire dest.
Renvoyez l’adresse dest.
Exercice : arrset
Fichiers à rendre : {src,test}/arrset.c
*Fonctions autorisées : aucune
Écrivez la fonction suivante :
void *arrset(void *array,
const void *elem,
unsigned int elem_size,
unsigned int n);
Elle doit initialiser n éléments du tableau array en utilisant l’élément pointé passé en paramètre. Chaque élément fait elem_size octets.
Il faut donc copier elem_size octets depuis elem pour chaque place dans le tableau.
Exemple d’utilisation :
int *array;
const unsigned int elem_size = sizeof(int);
const int default_value = 1970;
array = malloc(elem_size * 89);
arrset(array, &default_value, elem_size, 89);
// chaque case du tableau vaut maintenant 1970
unsigned int i;
i = 0;
while (i < 89) {
// dans un test unitaire:
// cr_assert(eq(i32, array[i], 1970), "array[%u] isn't equal to 1970", i);
// dans un main
printf("array[%u]: %d\n", i, array[i]);
i += 1;
}
free(array);
Exercice : memmove
Fichiers à rendre : {src,test}/memmove.c
*Fonctions autorisées : aucune
Cette fonction a pour but de déplacer le contenu d’une zone mémoire à une autre sachant que les deux zone mémoire peuvent se chevaucher. Elle a pour avantage de faciliter le déplacement vers la droite ou vers la gauche de ce qui est contenu dans notre tableau. C’est pratique lorsqu’on veut insérer un élément au milieu d’un tableau.
Elle finit par renvoyer dest.
void *stu_memmove(void *dest,
const void *src,
usigned int n);
Voici des exemples de tests unitaires que vous pouvez faire pour valider votre fonction.
Exercice : ajout à la libstu
Dépôt de rendu : libstu
Fichiers à rendre : {src,test}/{memset,memcpy,memmove,arrset}.c
Ajoutez vos fonctions et vos tests à la libstu pour pouvoir vous en servir dans d’autres projets.