Acquire the size of contents stored in smart pointers during runtime

Basically while I was trying to figure out the way to construct a graph node , I was little concerned regarding the size of my graph type starting from the top node !

Is there any convenient way to acquire the size of objects stored within the smart pointers type during runtime since , I can have input varying in any amount to the program ,

also I don't want to acquire size of each type individually using some loop / recursion

#[derive(Debug, Clone)]
struct graph {
    pub val : i32,
    pub childs: Option<Box<Vec<graph>>>
}

There isn't any built-in way to acquire the memory usage of a struct, no.

(Also, your graph type can only represent trees)

what if I did this !?

println!!("size: {:?}", std::mem::size_of_val(&Box::new(vec![...]));

it returns

size: 8

is there some way to this ..to directly get the size present within?

It's not going to get any more convenient than this:

impl Graph {
    fn total_size(&self) -> usize {
        let mut size = std::mem::size_of::<Self>();
        if let Some(ref children) = self.children {
            size += children.iter().map(Self::total_size).sum();
        }
        size
    }
}

Of course you'd have to adjust this to make sure you count each node only once if you changed your struct to represent arbitrary graphs.

Btw, there's no reason to use Box here.

2 Likes

ahhm I wasn't very clearly able to understand
why you mentioned call of function to Self inside the map() itself ?

Inside impl Graph { ... }, Self is the same as Graph. So Self::total_size is the same as Graph::total_size, which is how you refer to the associated function total_size. You could rewrite that line as

    size += children.iter().map(|child| child.total_size()).sum();

That is, call total_size on each child and add up all the sizes.

1 Like

I was aware about 'self' & 'Self'
but that made sense ....since now you are doing BFS travesal
to acquire the size of each elem in functional syntax

It's a DFS traversal.

Correction: if you are using Option<Box<Vec<Graph>>> you need to modify this code as follows:

        let mut size = std::mem::size_of::<Self>();
+       size += std::mem::size_of::<Vec<Self>>();
        if let Some(ref children) = self.children {
            size += children.iter().map(Self::total_size).sum();
        }
        size

This is because the Vec is stored in a separate heap allocation that's not counted by std::mem::size_of::<Self>(). If you don't use Box—and again, there's no point using it here—then the original code is correct.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.