C++对象被推回并且函数退出后矢量推回崩溃
问题是另一个类访问向量并删除迭代器时出现的愚蠢错误。与下面的代码无关。抱歉浪费你的时间。
我一定错过了一些基本的东西。 我有一个函数,它创建一个对象,操作它的数据,然后将其推入向量中。 函数退出的那一刻,程序因 SIGSEV 崩溃,我只能盯着 (Kdevelop gcc 4.5 gdb) :
/**
* The dtor only erases the elements, and note that if the
* elements themselves are pointers, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
~vector()
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); }
我不存储指针,我正在尝试存储实例化对象。
void Init::initIndividual(int ID, int gen)
{
Individual temp_person = Individual(ID,gen);
int inst_size = getRandom<int>(1,max_inst_size);
for (int k=0;k<inst_size;k++)
{
retry:
// (1) randomly choose a body part
int body_num = getRandom<int>(1,20);
body_part temp_part = get_body_part(body_num);
// NOTE: We need to make sure that the body part is unique!
std::vector<Instruction> already_existing = temp_person.get_instructions();
if (already_existing.size() > 0)
{
for (int a=0; a< already_existing.size();a++)
{
std::string name = already_existing[a].get_body_part();
if ( name.compare(temp_part.name) == 0 )
{ //if body part already exists in the list, retry!
goto retry;
}
}
}
// (2) Create a new Instruction for this body part
Instruction temp_inst = Instruction(temp_part.name,temp_part.max_angle,temp_part.min_angle);
// (3) Randomly pick a number of body parameters to use
int paramsize = getRandom<int>(1,max_params_size);
// (4) Randomly choose time and degree trajectory parameters for this body part and append!
for (int x=0;x < paramsize; x++)
{
float time = 0.0f;
int choice = 0;
// (4.a) If begin of body parameters
if (x==0)
{
//if always start at time = 0
if (static_time_init)
{
time = 0.0f;
}
//if randomly choose the init time
else if (!static_time_init)
{
time = getRandom<float>(0.0f,(float)(time_constrain-1));
}
}
// (4.b) if not @ start of params
else if(x!=0)
{
redo:
float previous_time = temp_inst.parameters.back().time; //get previous time
double incrementor = getRandom<double>(0.1,1.0); //increment time by min 0.1 max 1.0
time = previous_time + (float)incrementor;
if (time > time_constrain) //if current time is more than time constrain, redo
{
goto redo;
}
}
// (5) Randomly pick a degree to move to (within body part constrains)
float degree = getRandom<float>(temp_inst.get_min_angle(),temp_inst.get_max_angle());
Parameter foo = Parameter(time,degree);
temp_inst.add_parameter(Parameter(time,degree));
}
temp_person.add_Instruction(temp_inst);
}
temp_person.endtime = time_constrain;
}
这就是整个函数。
std::vector<Individual> population;
Push_back 函数在推回对象时不会复制对象吗? 析构函数是否被调用,因为 Push_back 试图销毁 temp_person ? 我没有在Individual类中定义复制运算符。 我以前也遇到过这个问题,但一直没有弄清楚。 发生这种情况是因为函数末尾的 temp_person 超出了范围吗? 谢谢 !
编辑:个人类
class Individual
{
friend class Population;
friend class Crossover;
friend class Init;
private:
std::string xml_file;
char *arg4;
protected:
bool saved, mutated, dead;
unsigned int UID, generation;
int executions;
std::vector<Instruction> instructions;
int father_UID, mother_UID;
double eta,endtime;
public:
int uniform;
float fitness;
pthread_mutex_t thread_mutex;
//Some other functions irrelevant
请注意,指令向量有另一个结构向量。
class Instruction
{
friend class Crossover;
private:
unsigned int param_size;
float max_angle, min_angle;
bool micro_mutated;
public:
std::string body_part;
std::vector<Parameter> parameters;
//other stuff
class Parameter
{
public:
float time;
float degree;
Parameter(float t,float d);
};
这里没什么疯狂的。
这可能是由population.push_back获得的浅拷贝的问题吗?
The problem was a stupid error from another class accessing the vector and deleting iterators. Nothing to do with the code below. Sorry to waste your time.
I must be missing something elementary.
I've got a function which creates an object, manipulates it's data and then pushes it into a vector.
The moment the function exits, the program crashes with a SIGSEV, and I'm left staring at (Kdevelop gcc 4.5 gdb) :
/**
* The dtor only erases the elements, and note that if the
* elements themselves are pointers, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
~vector()
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); }
I am not storing pointers, I'm trying to store instantiated objects.
void Init::initIndividual(int ID, int gen)
{
Individual temp_person = Individual(ID,gen);
int inst_size = getRandom<int>(1,max_inst_size);
for (int k=0;k<inst_size;k++)
{
retry:
// (1) randomly choose a body part
int body_num = getRandom<int>(1,20);
body_part temp_part = get_body_part(body_num);
// NOTE: We need to make sure that the body part is unique!
std::vector<Instruction> already_existing = temp_person.get_instructions();
if (already_existing.size() > 0)
{
for (int a=0; a< already_existing.size();a++)
{
std::string name = already_existing[a].get_body_part();
if ( name.compare(temp_part.name) == 0 )
{ //if body part already exists in the list, retry!
goto retry;
}
}
}
// (2) Create a new Instruction for this body part
Instruction temp_inst = Instruction(temp_part.name,temp_part.max_angle,temp_part.min_angle);
// (3) Randomly pick a number of body parameters to use
int paramsize = getRandom<int>(1,max_params_size);
// (4) Randomly choose time and degree trajectory parameters for this body part and append!
for (int x=0;x < paramsize; x++)
{
float time = 0.0f;
int choice = 0;
// (4.a) If begin of body parameters
if (x==0)
{
//if always start at time = 0
if (static_time_init)
{
time = 0.0f;
}
//if randomly choose the init time
else if (!static_time_init)
{
time = getRandom<float>(0.0f,(float)(time_constrain-1));
}
}
// (4.b) if not @ start of params
else if(x!=0)
{
redo:
float previous_time = temp_inst.parameters.back().time; //get previous time
double incrementor = getRandom<double>(0.1,1.0); //increment time by min 0.1 max 1.0
time = previous_time + (float)incrementor;
if (time > time_constrain) //if current time is more than time constrain, redo
{
goto redo;
}
}
// (5) Randomly pick a degree to move to (within body part constrains)
float degree = getRandom<float>(temp_inst.get_min_angle(),temp_inst.get_max_angle());
Parameter foo = Parameter(time,degree);
temp_inst.add_parameter(Parameter(time,degree));
}
temp_person.add_Instruction(temp_inst);
}
temp_person.endtime = time_constrain;
}
That is the entire function.
std::vector<Individual> population;
Doesn't the push_back function copy the object when pushing it back ?
Is the destructor invoked because push_back is trying to destroy temp_person ?
I have not defined a copy operator in class Individual.
I have run into this problem before and never figured it out.
Does this happen because at the end of the function temp_person is out of scope ?
Thank you !
Edit: Class Individual
class Individual
{
friend class Population;
friend class Crossover;
friend class Init;
private:
std::string xml_file;
char *arg4;
protected:
bool saved, mutated, dead;
unsigned int UID, generation;
int executions;
std::vector<Instruction> instructions;
int father_UID, mother_UID;
double eta,endtime;
public:
int uniform;
float fitness;
pthread_mutex_t thread_mutex;
//Some other functions irrelevant
Please note, that the vector of instructions has another vector of structs.
class Instruction
{
friend class Crossover;
private:
unsigned int param_size;
float max_angle, min_angle;
bool micro_mutated;
public:
std::string body_part;
std::vector<Parameter> parameters;
//other stuff
class Parameter
{
public:
float time;
float degree;
Parameter(float t,float d);
};
Nothing crazy here.
Could this be a problem of a shallow copy obtained by the population.push_back ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
复制
pthread_mutex_t
没有意义。我敢打赌这就是问题的一部分。我也对你的char*
表示怀疑;谁拥有它?我认为
pthread_mutex_t
无法复制的理由是:获取初始化互斥体的唯一有记录的方法是使用pthread_mutex_init
。此外,所有pthread_mutex_*
函数都使用指针传递来操作互斥体(与pthread_thread_t
等不同)。Copying a
pthread_mutex_t
is not meaningful. I'd wager that's part of the problem. I have suspicions about yourchar*
too; who owns it?My justification as to why I believe
pthread_mutex_t
can't be copied: the only documented way to obtain an initialized mutex is from usingpthread_mutex_init
. Additionally, all thepthread_mutex_*
functions manipulate mutexes using pass-by-pointer (unlike e.g.pthread_thread_t
).是的,确实如此。
不,事实并非如此。调用它是因为临时对象在函数结束时被销毁。
让我们看看类的声明。
是的,临时对象被破坏了,但是如果类没问题,这应该不是问题。再次强调——我们需要查看代码。
我敢打赌它与构造函数/析构函数有关(:
顺便说一下,population 是全局的吗?Outch!
Yes, it does.
No, it is not. It is called because the temp object is destroyed at the end of the function.
Let us see the declaration of the class.
Yes, the temp object is destroyed, but if the class is OK, this should not be a problem. Again - we need to see the code.
I bet it's something with the constructor/destructor (:
By the way, is
population
global? Outch!问题是另一个类访问向量并删除迭代器时出现的愚蠢错误。与上面的代码无关。抱歉浪费您的时间。
The problem was a stupid error from another class accessing the vector and deleting iterators. Nothing to do with the code above. Sorry to waste your time.