Segmentation fault when using a shared_ptr
c++, c++11, design-patterns, overloading, shared-ptr
Solution
This is not how `std::shared_ptr` works. You are creating your instances of `ParticleEmitter` on the stack, but `std::shared_ptr` is used to manage instances which are created on the heap. In your code, when you add a new emitter to the `ParticleManager`, and wrap it into a shared pointer, the emitter is destroyed when the `particleEmitters` vector is destroyed (when, in turn, your `ofApp` instance is destroyed) and is thus destroyed regardless.
When the instance of `ofApp` is destroyed, both the instance of `ofxCurlNoise` and `particleEmitters` are destroyed (in that order). So ofxCurlNoise will in turn destroy the `particleManager`, which manages your shared pointers, which will then delete your particle emitters (which were originally created on the stack). After all that is done, the `particleEmitters` vector is getting destroyed, and the runtime system will try to destroy your particle emitters again, leading to the error you are seeing.
Furthermore, shared pointers are used to model shared ownership semantics, which I don't see in your use case. I think you'd be better off to either use `std::unique_ptr` to manage instances created on the heap, or to not use smart pointers at all and create everything on the stack (which you are almost doing already).
Problem
I am making a particle system and I'm struggling with how to structure my code. The idea is that a user can create one or several `ParticleEmitter` objects that are passed to a `ParticleManager` object via the `ofxCurlNoise` object. Now, I want that when the user updates the `ParticleEmitters` objects, the `ParticleManager` object sees the changes made. So I used shared pointers but I have segmentation faults at different times, whether I use one `ParticleEmitter` (segmentation fault when the program starts) or a `vector<ParticleEmitter>` (segmentation fault when the program exits). What is wrong with this? Is there a design pattern for doing what I'm trying to do? ofApp.h ``` #include "ofxCurlNoise.h" class ofApp : public ofBaseApp{ // ParticleEmitter particleEmitter; vector<ParticleEmitter> particleEmitters; ofxCurlNoise curlNoise; public: void setup(); }; ``` ofApp.cpp ``` #include "ofApp.h" void ofApp::setup(){ // This produces a segfault as soon as the program starts // particleEmitter.setup(); // curlNoise.setup(particleEmitter, 1024*256); // This produces a segfault when the program exits ParticleEmitter emitter; emitter.setup(); particleEmitters.push_back(emitter); curlNoise.setup(particleEmitters, 1024*256); } ``` ofxCurlNoise.h ``` #include "ParticleManager.h" class ofxCurlNoise { ParticleManager particleManager; public: void setup(ParticleEmitter& emitter, int n); void setup(vector<ParticleEmitter>& emitters, int n); private: void setup(int n); }; ``` ofxCurlNoise.cpp ``` #include "ofxCurlNoise.h" void ofxCurlNoise::setup(ParticleEmitter& emitter, int n){ particleManager.addEmitter(shared_ptr<ParticleEmitter>(&emitter)); setup(n); } void ofxCurlNoise::setup(vector<ParticleEmitter>& emitters, int n){ for(auto& e : emitters){ particleManager.addEmitter(shared_ptr<ParticleEmitter>(&e)); } setup(n); } void ofxCurlNoise::setup(int n){ particleManager.setup(n); } ``` ParticleManager.h ``` #include "ParticleEmitter.h" class ParticleManager{ vector<shared_ptr<ParticleEmitter>> emitters; public: void addEmitter(const shared_ptr<ParticleEmitter>& emitter); void setup(int n); }; ``` ParticleManager.cpp ``` #include "ParticleManager.h" void ParticleManager::setup(int n){ //... } void ParticleManager::addEmitter(const shared_ptr<ParticleEmitter>& emitter){ emitters.push_back(emitter); } ```