C++对象被推回并且函数退出后矢量推回崩溃

发布于 2024-11-16 19:59:53 字数 4177 浏览 4 评论 0原文

问题是另一个类访问向量并删除迭代器时出现的愚蠢错误。与下面的代码无关。抱歉浪费你的时间。

我一定错过了一些基本的东西。 我有一个函数,它创建一个对象,操作它的数据,然后将其推入向量中。 函数退出的那一刻,程序因 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦幻之岛 2024-11-23 19:59:53
pthread_mutex_t thread_mutex;

复制pthread_mutex_t没有意义。我敢打赌这就是问题的一部分。我也对你的 char* 表示怀疑;谁拥有它?


我认为 pthread_mutex_t 无法复制的理由是:获取初始化互斥体的唯一有记录的方法是使用 pthread_mutex_init。此外,所有pthread_mutex_*函数都使用指针传递来操作互斥体(与pthread_thread_t等不同)。

pthread_mutex_t thread_mutex;

Copying a pthread_mutex_t is not meaningful. I'd wager that's part of the problem. I have suspicions about your char* 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 using pthread_mutex_init. Additionally, all the pthread_mutex_* functions manipulate mutexes using pass-by-pointer (unlike e.g. pthread_thread_t).

撩发小公举 2024-11-23 19:59:53
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. 

让我们看看类的声明。

Does this happen because at the end of the function temp_person is out of scope ?

是的,临时对象被破坏了,但是如果类没问题,这应该不是问题。再次强调——我们需要查看代码。

我敢打赌它与构造函数/析构函数有关(:

顺便说一下,population 是全局的吗?Outch!

Doesn't the push_back function copy the object when pushing it back ? 

Yes, it does.

Is the destructor invoked because push_back is trying to destroy temp_person?

No, it is not. It is called because the temp object is destroyed at the end of the function.

I have not defined a copy operator in class Individual. 

Let us see the declaration of the class.

Does this happen because at the end of the function temp_person is out of scope ?

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!

羅雙樹 2024-11-23 19:59:53

问题是另一个类访问向量并删除迭代器时出现的愚蠢错误。与上面的代码无关。抱歉浪费您的时间。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文