ПРОБЛЕМА: Работа с глубоко вложенными указателями в C ++ - PullRequest
1 голос
/ 25 июня 2010

Я определяю эту структуру:

struct s_molecule
{
  std::string res_name;
  std::vector<t_particle> my_particles;
  std::vector<t_bond> my_bonds;
  std::vector<t_angle> my_angles;
  std::vector<t_dihedral> my_dihedrals;

  s_molecule& operator=(const s_molecule &to_assign)
  {
    res_name = to_assign.res_name;
    my_particles = to_assign.my_particles;
    my_bonds = to_assign.my_bonds;
    my_angles = to_assign.my_angles;
    my_dihedrals = to_assign.my_dihedrals;
    return *this;
  }
};

и эти структуры:

typedef struct s_particle
{
  t_coordinates position;
  double charge;
  double mass;
  std::string name;
  std::vector<t_lj_param>::iterator my_particle_kind_iter;

  s_particle& operator=(const s_particle &to_assign)
  {
    position = to_assign.position;
    charge = to_assign.charge;
    mass = to_assign.mass;
    name = to_assign.name;
    my_particle_kind_iter = to_assign.my_particle_kind_iter;
    return *this;
  }
} t_particle;

struct s_bond
{
  t_particle * particle_1;
  t_particle * particle_2;
  std::vector<t_bond_param>::iterator my_bond_kind_iter;

  s_bond& operator=(const s_bond &to_assign)
  {
    particle_1 = to_assign.particle_1;
    particle_2 = to_assign.particle_2;
    my_bond_kind_iter = to_assign.my_bond_kind_iter;
    return *this;
  }
};

, а затем в своем коде я возвращаю указатель на s_molecule (typedef'd to t_molecule, новсе еще).

Используя этот указатель, я могу заставить этот код работать:

for  (unsigned int i = 0;
      i < current_molecule->my_particles.size();
      i++)
    {
      std::cout << "Particle " 
        << current_molecule->my_particles[i].name << std::endl
            << "Charge: " 
        << current_molecule->my_particles[i].charge << std::endl
        << "Mass: " 
        << current_molecule->my_particles[i].mass << std::endl
        << "Particle Kind Name: " 
        << (*current_molecule->my_particles[i].my_particle_kind_iter).atom_kind_name 
        << std::endl
        << "x: " << current_molecule->my_particles[i].position.x 
        << " y: " << current_molecule->my_particles[i].position.y
    #ifdef USE_3D_GEOM
        << "z: " << current_molecule->my_particles[i].position.z
    #endif
        << std::endl;
    }

Если я заменю его на:

for  (std::vector<t_particle>::iterator it = current_molecule->my_particles.begin();
      it !=current_molecule->my_particles.end();
      it++)
    {
      std::cout << "Particle " 
        << (*it).name << std::endl
            << "Charge: " 
        << (*it).charge << std::endl
        << "Mass: " 
        << (*it).mass << std::endl
        << "Particle Kind Name: " 
        << (*(*it).my_particle_kind_iter).atom_kind_name 
        << std::endl
        << "x: " << (*it).position.x 
        << " y: " << (*it).position.y
    #ifdef USE_3D_GEOM
        << "z: " << (*it).position.z
    #endif
        << std::endl;
    }

Теперь я получаю неприятные ошибки...

Не слишком много здесь, но я также получаю ошибки, когда пытаюсь это сделать:

std::cout << "Bond ATOMS : " 
          << (*current_molecule).my_bonds[0].particle_1->name
          << std::endl

И снова current_molecule - указатель на структуру s_molecule, котораясодержит массивы структур, которые в свою очередь либо имеют непосредственно переменные, либо являются указателями.Я не могу заставить эти множественные слои косвенности работать.Предложения по исправлению этих segfaults.

К вашему сведению Я компилирую на Linux Centos 5.4 с g ++ и использую собственную систему makefile.

Ответы [ 4 ]

0 голосов
/ 27 августа 2010

Опять же, этот вопрос был дан ответ здесь: Странная проблема с указателями в C ++ DeadMG. Извините за двойной пост.

0 голосов
/ 25 июня 2010

Дикое предположение: вы используете общие библиотеки. Я помню, как испытывал трудности при передаче STL-контейнеров назад и вперед через границы общих библиотек.

0 голосов
/ 25 июня 2010

Джейсон (OP) спросил в комментарии Дэвида Родригеса:

Возвращаете ли вы указатель на локальную переменную?

Джейсон ответил:

Нет, это ptr для переменной класса.Класс существует очень много (он содержит функцию, которая возвращает молекулу).

Если вы не говорите об истинной переменной класса (квалифицированной как static), тот факт, что класс существует, не имеет к этому никакого отношения. Экземпляры класса существуют, и они могли бы перестать существовать, даже если вы просто вызвали для них функцию.

Таким образом, вопрос заключается в следующем:

  • Существует ли экземпляр класса, который возвратил указатель current_molecule, по-прежнему существует?
  • Или current_molecule квалифицирован как static, то есть является истинной переменной класса?

Если ответ на оба вопроса «нет», вы находитесь в округе Undefined.

В этот момент очень важно, чтобы вы опубликовали исходный код, который мы могли бы использовать здесьна самом деле воспроизвести проблему;он может быть расположен в источнике, который вы нам не показываете.

0 голосов
/ 25 июня 2010

@ sbi Спасибо за хороший совет! Я полагаю, что вы правы - оператор перегруженного назначения не нужен и должен быть отменен.

Я следовал подходу комментирования и очень растерялся. По сути, в функции, которая передает указатель на мою конкретную молекулу в основную функцию для печати, я могу прекрасно видеть все данные в этой молекуле (связи, частицы, имя и т. Д.), Печатая cout's.

Как только я передаю его в main как ptr, если я использую этот ptr с итератором, я получаю segfault. Другими словами. Кроме того, по какой-то причине данные о связях (которые я могу свободно распечатать в своей функции, которая возвращает указатель) также могут ошибаться, если я пытаюсь их распечатать, даже если я использую [] для индексации вектора связей (который работает для частицы вектор).

Это лучшая информация, которую я могу дать на данный момент.

...