Miguel Garcia
Miguel Garcia

Reputation: 61

Ocaml - Accessing components in an array of records

I have a array of record type tt - originally with more components ;-) - and like to change its values within a for loop:

type tt={mutable x: int};;
let f0={x= -1};;
let max=10;;
let ff=Array.create max f0;;
for i=0 to max-1 do ff.(i).x <- i;done;;

Nevertheless, all fields of ff have the value 9 instead of having values from 0 to 9. Is ff.(i).x correct? I also tried

for i=0 to max-1 do f0.x <- i;ff.(i) <- f0;done;;

but with the same result... (I'm using OCaml version 4.00.1) What is wrong? I would be happy if somebody could give me a hint!

Upvotes: 6

Views: 499

Answers (3)

Jack
Jack

Reputation: 133577

The problem is that, since the record is mutable, it is stored by reference and not by value as you would expect from a non mutable data type (as an integer) so when you do

let ff=Array.create 10 f0;;

you are actually storing 10 references to the same record. And then each iteration of

for i=0 to max-1 do ff.(i).x <- i;done;;

just updates the same reference multiple times, so since last iteration is with i = 9 then the only real record contained in the array gets that value.

What you need to do is to create 10 different record such with:

# type tt = {mutable x: int};;
type tt = { mutable x : int; }
# let f = Array.init 10 (fun i -> { x = -1});;
val f : tt array =
  [|{x = -1}; {x = -1}; {x = -1}; {x = -1}; {x = -1}; {x = -1}; {x = -1};
    {x = -1}; {x = -1}; {x = -1}|]
# f.(2).x <- 2;;
- : unit = ()
# f;;
- : tt array =
[|{x = -1}; {x = -1}; {x = 2}; {x = -1}; {x = -1}; {x = -1}; {x = -1};
  {x = -1}; {x = -1}; {x = -1}|]

Upvotes: 3

jrouquie
jrouquie

Reputation: 4415

The problem is that all cells of the ff array contain the same element, namely f0. You need to create a fresh element of type tt for each cell. This is a way to do so:

type tt={mutable x: int};;
let max=10;;
let ff=Array.init max (fun i -> {x= i});;

Now you can modify a cell without affecting the other cells.

Upvotes: 4

gasche
gasche

Reputation: 31459

This is a classic mistake that beginners do with Array.create and mutable state. I have explained it in detail there. The summary is that Array.create n foo does not create copies of foo (how could it?), it creates an array of cases all pointing to the same foo.

Upvotes: 9

Related Questions