使用shared_ptr时出现分段错误 [英] Segmentation fault when using a shared_ptr
问题描述
我正在制作一个粒子系统,并且正在为如何构建代码而苦苦挣扎。这个想法是,用户可以创建一个或多个 ParticleEmitter
对象,这些对象通过<$传递给 ParticleManager
对象c $ c> ofxCurlNoise 对象。
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.
现在,我希望当用户更新 ParticleEmitters
对象时, ParticleManager
对象可以看到所做的更改。因此,我使用了共享指针,但是在不同的时间出现了段错误,无论是使用一个 ParticleEmitter
(程序启动时出现段错误)还是 vector < ParticleEmitter>
(程序退出时出现分段错误)。
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);
}
推荐答案
这不是 std :: shared_ptr
有效。您正在堆栈上创建 ParticleEmitter
的实例,但是 std :: shared_ptr
用于管理创建的实例在堆上。在您的代码中,将新的发射器添加到 ParticleManager
并将其包装到共享指针中时,当 particleEmitters 时,发射器将被破坏
向量被销毁(反过来,当您的 ofApp
实例被销毁时)也因此被销毁。
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.
当 ofApp
的实例被销毁时, ofxCurlNoise
和的实例都被销毁。粒子发射器
被破坏(按此顺序)。因此,ofxCurlNoise会破坏 particleManager
,后者管理您的共享指针,然后将删除您的粒子发射器(最初在堆栈上创建)。完成所有这些操作后, particleEmitters
向量被破坏了,运行时系统将尝试再次破坏您的粒子发射器,从而导致您看到的错误。
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.
此外,共享指针用于建模共享所有权语义,在您的用例中我看不到。我认为您最好使用 std :: unique_ptr
来管理在堆上创建的实例,或者根本不使用智能指针并在堆栈上创建所有内容(您几乎已经在这样做了。)
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).
这篇关于使用shared_ptr时出现分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!