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

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

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;
    }

Теперь я получаю неприятные сегфо...

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

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

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

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

4 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам