Quatre copies de matrice, deux fausses
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 2 — Le langage OCaml
Énoncé
Que contient la matrice après chacune de ces quatre manipulations ?
(* a *) let a = Array.make 3 (Array.make 2 0) in a.(0).(0) <- 7
(* b *) let b = Array.make_matrix 3 2 0 in b.(0).(0) <- 7
(* c *) let m = Array.make_matrix 2 2 0 in
let c = Array.copy m in c.(0).(0) <- 9
(* d *) let m2 = Array.make_matrix 2 2 0 in
let d = Array.map Array.copy m2 in d.(0).(0) <- 9Corrigé
Les valeurs mesurées :
(a) a = [|7;0|] [|7;0|] [|7;0|] <-- LES TROIS lignes ont change
(b) b = [|7;0|] [|0;0|] [|0;0|] correct
(c) m = [|9;0|] [|0;0|] <-- l'ORIGINAL a change
c = [|9;0|] [|0;0|]
(d) m2 = [|0;0|] [|0;0|] l'original est intact
d = [|9;0|] [|0;0|]
(a) Le piège de Array.make. Son second argument est une valeur, évaluée une seule fois, et cette valeur est ici un tableau. Les trois cases reçoivent donc trois fois le même tableau — pas trois copies. Array.make_matrix existe exactement pour cela : il alloue une ligne neuve par indice, et c'est la seule forme correcte, en (b).
(c) Le caractère superficiel de Array.copy. L'annexe le dit dans les mots mêmes : la copie l'est « y compris [dans] le caractère superficiel de cette copie ». Array.copy m fabrique un tableau extérieur neuf, dont les cases contiennent les mêmes lignes. Écrire c.(0).(0) traverse la case partagée et modifie l'original.
Le tableau extérieur, lui, est bien distinct : c.(0) <- [| 5; 5 |] remplace une ligne dans c sans toucher à m — mesuré aussi. La copie est superficielle d'un cran exactement.
(d) La copie profonde recopie chaque ligne : Array.map Array.copy m2. C'est la forme à écrire dès qu'on veut travailler sur une matrice sans abîmer l'entrée.
Ce que l'exercice éprouve. Le partage n'est pas visible dans le type : int array array ne dit rien de qui partage quoi. C'est le seul endroit du langage où la gestion automatique de la mémoire ne vous dispense pas de savoir où sont les objets. Le chapitre chap:memoire le reprend sous le nom d'aliasing.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.