From b71d2051cb8be3288e237cb1ceb8c9b81ed4850e Mon Sep 17 00:00:00 2001 From: iliya <iliya.saroukha@hes-so.ch> Date: Fri, 3 Nov 2023 15:40:33 +0100 Subject: [PATCH] feat: serie3 finished --- serie3/ex4/.gitignore | 2 ++ serie3/ex4/Makefile | 26 ++++++++++++++++ serie3/ex4/ex4.md | 69 +++++++++++++++++++++++++++++++++++++++++++ serie3/ex4/prog.c | 26 ++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 serie3/ex4/.gitignore create mode 100644 serie3/ex4/Makefile create mode 100644 serie3/ex4/ex4.md create mode 100644 serie3/ex4/prog.c diff --git a/serie3/ex4/.gitignore b/serie3/ex4/.gitignore new file mode 100644 index 0000000..b6de771 --- /dev/null +++ b/serie3/ex4/.gitignore @@ -0,0 +1,2 @@ +*.o +prog diff --git a/serie3/ex4/Makefile b/serie3/ex4/Makefile new file mode 100644 index 0000000..f702d8a --- /dev/null +++ b/serie3/ex4/Makefile @@ -0,0 +1,26 @@ +CC := clang +CFLAGS := -g -pedantic -Wall -Wextra -std=c11 +LDFLAGS := -fsanitize=address -fsanitize=leak -fsanitize=undefined -lm -lpthread +TARGET := prog + +all: $(TARGET) + +$(TARGET): prog.o + @printf "=================== Building executable ===================\n" + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) + @printf "\n" + +%.o: %.c + @printf "================== Building object files ==================\n" + $(CC) $(CFLAGS) -c $< + @printf "\n" + + +.PHONY: clean + +clean: + rm -f *.o $(TARGET) + +.PHONY: rebuild + +rebuild: clean all diff --git a/serie3/ex4/ex4.md b/serie3/ex4/ex4.md new file mode 100644 index 0000000..2865ccf --- /dev/null +++ b/serie3/ex4/ex4.md @@ -0,0 +1,69 @@ +# Exercice 4 + +Soit le code suivant : + +```c +#define MAX_STRING_SIZE 256 + +char *strtoupper(char *string) { + static char buffer[MAX_STRING_SIZE]; + int index; + for (index = 0; string[index]; index++) { + // on part du principe que toupper est MT-safe et réentrant + buffer[index] = toupper(string[index]); + } + buffer[index] = 0; + return buffer; +} +``` + +## Questions + +1. Le code est-il réentrant ? +2. Le code est-il _thread-safe_ ? +3. Dans la négative, modifiez le code pour qu'il devienne réentrant **et** +thread-safe. À noter que modifier l'interface est autorisé. + + +## Réponses + +1. Le code **n'est pas réentrant** car si l'exécution de la fonction `strtoupper` +est interrompue pendant son exécution est qu'elle est appellée par cette fois-ci +avec une autre chaîne de caractères que l'exécution initiale, le buffer pointera +désormais sur la chaîne de caractères créée sur la base de la seconde exécution +et non pas sur la première exécution. Une fonction réentrante ne doit pas référencer / +retourner de pointeur sur des données statiques ou globales, or dans ce cas elle +le fait avec la variable `buffer` qui a un "comportement" global mais une visibilité +locale. +2. Le code **n'est pas thread-safe** pour la même raison que ci-dessus car la +variable statique `static char buffer` risque d'être modifiée par l'exécution +d'un autre thread. +3. ```c + #include <ctype.h> + #include <stdio.h> + #include <stdlib.h> + + #define MAX_STRING_SIZE 256 + + char *strtoupper(char *string) { + char *buffer = calloc(MAX_STRING_SIZE, sizeof(char)); + int index; + + for (index = 0; string[index]; index++) { + buffer[index] = toupper(string[index]); + } + + return buffer; + } + + int main(void) { + char *test_str = "Hello World!"; + char *res = strtoupper(test_str); + + fprintf(stdout, "Result: %s\n", res); + + free(res); + return EXIT_SUCCESS; + } + ``` + diff --git a/serie3/ex4/prog.c b/serie3/ex4/prog.c new file mode 100644 index 0000000..17d6e5a --- /dev/null +++ b/serie3/ex4/prog.c @@ -0,0 +1,26 @@ +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> + +#define MAX_STRING_SIZE 256 + +char *strtoupper(char *string) { + char *buffer = calloc(MAX_STRING_SIZE, sizeof(char)); + int index; + + for (index = 0; string[index]; index++) { + buffer[index] = toupper(string[index]); + } + + return buffer; +} + +int main(void) { + char *test_str = "Hello World!"; + char *res = strtoupper(test_str); + + fprintf(stdout, "Result: %s\n", res); + + free(res); + return EXIT_SUCCESS; +} -- GitLab