How to use a container of heap allocated objects

I need to implement following:

A container (may be array or map or set) of heap allocated objects.
The container will own these objects.
But the rest of my program needs to access these objects and mutate them.

What Rust types should I use?

Regards
Dibyendu

I think you’re giving too vague of a description here unfortunately in order for others to be able to give concrete suggestions on what types and/or program structure to use. Some things that aren’t clear for example: Is this supposed to be a kind of single(ton) instance of the container for the whole program or do you want to have multiple of them? Does your program need to modify the container itself or only the objects inside of the container? Are the objects all of the same type?

Perhaps, if you give us more details about what kind of program you’re planning to write that lead you to needing such a container owning some objects, things would become much clearer. What problem/task is this program going to solve (and, roughly, what is your plan of how to solve it using this appropriate type of container you are looking for)? Giving some further motivation here also helps avoiding any (potential) XY problem situation, since there might be a more appropriate way to solve your actual problem that doesn’t involve any “container of heap allocated objects” where “the rest of my program needs to access these objects and mutate them”.

Sorry if my question wasn't clear. I am trying to figure out how one can hold heap objects in a container and allow these objects to be mutated. Specifically I am trying to understand whether this requires using Rc, or Refcell wrapped objects.

I think the rest of the detail doesn't matter.

p.s. It doesn't need to be thread safe because I only intend it to be used in a single thread.

With a mutable reference to the container, you can typically modify the contents in the container. E.g. you can modify the elements in a Vec if you have a mutable reference to the Vec.

As alice said, the usual way to modify something inside of a container is by having mutable access to the container itself. To give some code example

#[derive(Debug)]
struct SomeObject {
    field1: i32,
    field2: f32,
}

fn main() {
    // let’s heap allocate the objects individually for no reason
    let o1 = Box::new(SomeObject {
        field1: 42,
        field2: 3.1415926,
    });
    let o2 = Box::new(SomeObject {
        field1: 12345,
        field2: -2.5,
    });

    // put it into a container, e.g. a Vec
    let mut x: Vec<Box<SomeObject>> = vec![o1, o2];

    // and let’s mutate it in the_rest_of_my_program
    the_rest_of_my_program(&mut x);
    
    // let’s see the results
    println!("{:#?}", x);
}

fn the_rest_of_my_program(container: &mut Vec<Box<SomeObject>>) {
    // can mutate the container itself
    container.push(Box::new(SomeObject {
        field1: 0,
        field2: 0.0,
    }));
    
    // as well as the objects inside
    container[1].field2 = 1_000_000.0;
}

(in the playground)

Output:

[
    SomeObject {
        field1: 42,
        field2: 3.1415925,
    },
    SomeObject {
        field1: 12345,
        field2: 1000000.0,
    },
    SomeObject {
        field1: 0,
        field2: 0.0,
    },
]

I’m also not 100% sure what you understand under the term “heap object”. Usually heap vs. stack doesn’t make a difference when it comes to whether something can be modified in Rust or not. Of course, there are ownership primitives such as Rc that are implemented using the heap and that also do influence whether or how things can be modified.

If you want to learn more about Rc and RefCell in general, you could read the Smart Pointers chapter of the book. (Understanding those may also require some knowledge from most of the previous chapters, too.)


If you are having trouble or are uncertain about certain aspects of Rc or RefCell, feel free to ask more concrete questions. Or if you’re trying to figure out which of these you might need to implement a specific algorithm or solve a specific problem.

1 Like

Thanks for the answers, that's very helpful.