num3ric / Cinder-Skinning

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Possible memory leak due to circular shared_ptr reference

gaborpapp opened this issue · comments

There is a circular reference between Node's mParent and the parent's mChildren, which prevents from releasing the memory.

Hi Gabor, thanks a lot for looking into this code and filing this issue! Reading around, I presume one solution would be to use std::weak_ptr for the pointer pointing to the parent.

Another one would be to have the skeleton class store std::unique_ptr to the nodes, and refactor the rest of the code to use only raw pointers. I'll have to dive back into this to see how that would be done.

Any preference? What do you think?

Hi Éric,

I used the std::weak_ptr solution in Cinder-Assimp, you can find it in the dev branch. I preferred this, because it seemed simpler.

Good catch. If you do go with the std::weak_ptr route, I'd profile before and after with a large graph of Node's - it looks like you using mParent in the update method, and using a weak_ptr<> will require constructing (and checking if not empty) a shared_ptr in every update(). If the Node graphs are only meant to be manipulated from one thread, you won't benefit much from using the weak_ptr over a raw pointer (and calling setParent( nullptr ) in destructor) anyway, but then profiling will only tell if you'll gain anything by using the latter.

I've decided to go with the weak_ptr solution. Before the cost of constructing a shared_ptr starts to matter, I think there are other things which could be optimized, namely how the absolute transformations matrices are updated. Instead of updating all transformations every time, we could be smart about it: the absolute rotation & scaling don't need update if only the parent's position has changed. Similar logic could be applied to other transforms.

I'm still open to the idea of switching to raw pointers, but it would require a significant rewrite.

(Sorry for merging these changes straight into master. I probably should have kept them in a dev branch.)